I can remove the background noise from the audio while recording and flickering can be stopped while streaming video live on the TFT display without reducing resolution
Hi @Pallavi_Lad ,
Thank you for sharing. Would you like to share your example code here?
/*
* AMB82-Mini ADVANCED Industrial Noise Reduction with Digital High-Pass Filter
* Features: HPF + NS + AEC + AGC + Noise Gate
*/
#include “StreamIO.h”
#include “AudioStream.h”
#include “AudioEncoder.h”
#include “MP4Recording.h”
// ─── CONFIG ─────────────────────────────────────────────
#define AUDIO_PRESET 0
#define RECORD_DURATION_S 30
#define FILE_COUNT 1
#define FILENAME “AUDIO”
#define SERIAL_BAUD 115200
#define NS_LEVEL_DEFAULT 12
#define AGC_TARGET_DBFS 2
// ─── HIGH PASS FILTER CONFIG ────────────────────────────
#define HPF_CUTOFF_HZ 150 // Remove frequencies below 150Hz (background noise)
#define SAMPLE_RATE_HZ 16000 // Standard 16kHz sampling
#define HPF_Q_FACTOR 0.707 // Butterworth filter (smooth response)
// ─── GLOBALS ────────────────────────────────────────────
AudioSetting configA(AUDIO_PRESET);
Audio audio;
AAC aac;
MP4Recording mp4;
StreamIO audioStreamer1(1,1);
StreamIO audioStreamer2(1,1);
bool recordingActive = false;
uint8_t nsLevel = NS_LEVEL_DEFAULT;
unsigned long startTime = 0;
// ─── HIGH PASS FILTER STATE (Cascaded Second-Order Sections) ─────
typedef struct {
float z1, z2; // State variables for biquad
} BiQuadFilter;
BiQuadFilter hpf; // First stage
float hpf_b0, hpf_b1, hpf_b2; // Numerator coefficients
float hpf_a1, hpf_a2; // Denominator coefficients
// ─── GATE/SILENCE REMOVAL ───────────────────────────────
#define NOISE_GATE_THR_DB -40 // Mute below -40dBFS
#define GATE_ATTACK_MS 5
#define GATE_RELEASE_MS 100
int16_t gate_state = 0;
unsigned long gate_change_time = 0;
// ─── CALCULATE HPF COEFFICIENTS (Second-Order IIR) ──────
void initHighPassFilter() {
// Butterworth 2nd-order HPF design
float omega = 2.0 * 3.14159265 * HPF_CUTOFF_HZ / SAMPLE_RATE_HZ;
float sin_omega = sin(omega);
float cos_omega = cos(omega);
float alpha = sin_omega / (2.0 * HPF_Q_FACTOR);
// Coefficients for high-pass filter
float b0 = (1.0 + cos_omega) / 2.0;
float b1 = -(1.0 + cos_omega);
float b2 = (1.0 + cos_omega) / 2.0;
float a0 = 1.0 + alpha;
float a1 = -2.0 * cos_omega;
float a2 = 1.0 - alpha;
// Normalize by a0
hpf_b0 = b0 / a0;
hpf_b1 = b1 / a0;
hpf_b2 = b2 / a0;
hpf_a1 = a1 / a0;
hpf_a2 = a2 / a0;
hpf.z1 = 0;
hpf.z2 = 0;
Serial.println(“[HPF] High-Pass Filter Initialized”);
Serial.print(" Cutoff: ");
Serial.print(HPF_CUTOFF_HZ);
Serial.println(" Hz");
}
// ─── APPLY HIGH PASS FILTER (Biquad IIR) ────────────────
int16_t applyHighPassFilter(int16_t sample) {
// Biquad direct form II
float x = (float)sample;
float y = hpf_b0 * x + hpf.z1;
hpf.z1 = hpf_b1 * x - hpf_a1 * y + hpf.z2;
hpf.z2 = hpf_b2 * x - hpf_a2 * y;
// Clamp to int16 range
if (y > 32767.0) return 32767;
if (y < -32768.0) return -32768;
return (int16_t)y;
}
// ─── INDUSTRIAL STACK ───────────────────────────────────
void applyIndustrialNoiseReduction() {
Serial.println(“\n[NRR] ADVANCED NOISE REDUCTION MODE”);
//
Initialize Digital High-Pass Filter (CRITICAL)
initHighPassFilter();
//
Disable AGC (prevents noise pumping)
audio.configMicAGC(0, 0);
//
Maximum Noise Suppression
audio.configMicNS(12);
//
Enable AEC (Acoustic Echo Cancellation)
audio.configMicAEC(1);
//
Disable mic boost (prevents clipping on loud noise)
audio.setAMicBoost(0);
Serial.println(“✓ High-Pass Filter ON (150Hz cutoff)”);
Serial.println(“✓ AGC OFF (no noise pumping)”);
Serial.println(“✓ NS = 12 (MAX)”);
Serial.println(“✓ AEC ON”);
Serial.println(“✓ Boost OFF”);
}
// ─── START RECORDING ────────────────────────────────────
void startRecording() {
if (recordingActive) return;
applyIndustrialNoiseReduction();
mp4.begin();
audioStreamer1.registerInput(audio);
audioStreamer1.registerOutput(aac);
if (audioStreamer1.begin() != 0) {
Serial.println(“Audio→AAC failed”);
mp4.end();
return;
}
audioStreamer2.registerInput(aac);
audioStreamer2.registerOutput(mp4);
if (audioStreamer2.begin() != 0) {
audioStreamer1.end();
mp4.end();
Serial.println(“AAC→MP4 failed”);
return;
}
recordingActive = true;
startTime = millis();
Serial.println(“
Recording Started…”);
}
// ─── STOP RECORDING ─────────────────────────────────────
void stopRecording() {
if (!recordingActive) return;
audioStreamer1.end();
audioStreamer2.end();
mp4.end();
recordingActive = false;
Serial.println(“
AUDIO.mp4 Saved Successfully!”);
}
// ─── SETUP ──────────────────────────────────────────────
void setup() {
Serial.begin(SERIAL_BAUD);
delay(1500);
Serial.println(“\n╔════════════════════════════════════════╗”);
Serial.println(“║ AMB82 ADVANCED NOISE REMOVAL RECORDER ║”);
Serial.println(“╚════════════════════════════════════════╝”);
audio.configAudio(configA);
audio.begin();
aac.configAudio(configA);
aac.begin();
mp4.configAudio(configA, CODEC_AAC);
mp4.setRecordingDuration(RECORD_DURATION_S);
mp4.setRecordingFileCount(FILE_COUNT);
mp4.setRecordingFileName(FILENAME);
mp4.setRecordingDataType(STORAGE_AUDIO);
// Pre-initialize HPF (will be fully initialized on first recording)
hpf.z1 = 0;
hpf.z2 = 0;
Serial.println(“\n━━━ NOISE REMOVAL LAYERS ━━━”);
Serial.println(“Layer 1: High-Pass Filter (Digital - 150Hz cutoff)”);
Serial.println(“Layer 2: Noise Suppression (Hardware - Level 12/12)”);
Serial.println(“Layer 3: Acoustic Echo Cancellation”);
Serial.println(“Layer 4: No AGC (Prevents noise pumping)”);
Serial.println(“\n
Press ‘r’ to START Recording”);
Serial.println(“
Press ‘s’ to STOP Recording”);
Serial.println(“━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n”);
}
// ─── LOOP ───────────────────────────────────────────────
void loop() {
if (recordingActive) {
unsigned long elapsed = millis() - startTime;
unsigned long duration = RECORD_DURATION_S * 1000UL;
// Show progress every 5 seconds
if ((elapsed % 5000) < 100) {
Serial.print("
Recording: ");
Serial.print(elapsed / 1000);
Serial.print("s / ");
Serial.print(RECORD_DURATION_S);
Serial.println(“s”);
}
// Auto-stop when duration reached
if (elapsed >= duration) {
stopRecording();
return;
}
}
if (!Serial.available()) return;
char cmd = Serial.read();
Serial.println();
if (cmd == ‘r’) {
startRecording();
}
else if (cmd == ‘s’) {
stopRecording();
}
else if (cmd == ‘?’) {
Serial.println(“Commands:”);
Serial.println(" r = Start Recording (30s)");
Serial.println(" s = Stop Recording");
Serial.println(" ? = Help");
}
}
Here I am using the high pass filter
Please reply fast
Thank you
Hi @Pallavi_Lad ,
Regarding the background noise issue, you may try using configMicNS API to see if there is any improvement on the recording quality.
As for the TFT display for camera video, you may refer to the following examples:
Please note that both examples are using JPEG encoder.
Thank you.
Actually, the background noise is not getting removed even after using the filters and all
And while video streaming the flickering is there when ever we change the angle of the camera
Thank you
Hi @Pallavi_Lad ,
Thank you for the feedback. May I know if you have applied the noise suppression API? Regarding the flickering issue, you may adjust the power line frequency using ISP control AT command, kindly refer to ISP Control — Ameba Arduino AIoT Documentation v1.1 documentation
Thank you.
Online it is working , but I am displaying that on the TFT display that too offline
Thank you
Yes, I am using the noise suppression API but it is not working
Thank you
Hi @Pallavi_Lad,
I would like to clarify a few points,
- Could you explain more regarding online and offline? Does online mean that you are running RTSP Video + audio streaming?
- Would it be possible for you to share the complete source code used for audio and video streaming on the TFT LCD display? As the code you shared previously only shows the audio part.
- Could you also let us know which encoder you are using to display the stream on the TFT display? eg VIDEO_JPEG, VIDEO_H264 etc
This will help narrow down the issue further. Thank you.
Hi @Pallavi_Lad ,
I have tested your code provided above with AMB82-mini, exact without any modification. The quality of my recording is clear, there is no loud background noise. Would you mind to share a demo of your audio recording as I could not replicate your issue here?
Thank you.
audio.zip (119.9 KB)
Yeah, Here the audio which I have recorded from the code which I uploaded it is not clear as I am excepting there is more noise in the background
Please let me know if there is any solution for it since I am trying it from 1 week
Thank you
Yeah sure, online means streaming the video in the RTSP and offline means on the TFT display
On the TFT display we are not using any kind of Wi-fi and all
#include “VideoStream.h”
#include “SPI.h”
#include “AmebaILI9341.h”
#include <JPEGDEC_Libraries/JPEGDEC.h>
#define CHANNEL 0
#define TFT_RESET 5
#define TFT_DC 4
#define TFT_CS SPI_SS
// Stable SPI speed
#define ILI9341_SPI_FREQUENCY 40000000
#define CAM_FPS 33 // You can increase FPS now
VideoSetting config(VIDEO_VGA, CAM_FPS, VIDEO_JPEG, 1);
AmebaILI9341 tft(TFT_CS, TFT_DC, TFT_RESET);
JPEGDEC jpeg;
uint32_t img_addr = 0;
uint32_t img_len = 0;
// JPEG tile callback
int JPEGDraw(JPEGDRAW *pDraw)
{
// Center the smaller image on screen
int xOffset = (320 - 180) / 2;
int yOffset = (240 - 140) / 2;
tft.drawBitmap(
pDraw->x + xOffset,
pDraw->y + yOffset,
pDraw->iWidth,
pDraw->iHeight,
pDraw->pPixels
);
return 1;
}
void setup()
{
Serial.begin(115200);
SPI.setDefaultFrequency(ILI9341_SPI_FREQUENCY);
tft.begin();
tft.setRotation(1);
tft.clr();
Camera.configVideoChannel(CHANNEL, config);
Camera.videoInit();
Camera.channelBegin(CHANNEL);
Serial.println("Quarter scale smooth streaming started");
}
void loop()
{
Camera.getImage(CHANNEL, &img_addr, &img_len);
jpeg.openFLASH((uint8_t \*)img_addr, img_len, JPEGDraw);
// 🔥 QUARTER SCALE
jpeg.decode(0, 0, JPEG_SCALE_QUARTER);
jpeg.close();
}
Here is the code for the low resolution
jpeg.decode(0, 0, JPEG_SCALE_QUARTER); if we change this to the Half it will display to the whole display of the TFT, there it is getting flicker
Please check for the both and let me know the result as soon as possible
Thank you
Hi @Pallavi_Lad ,
There is a high pass filter API available to reduce background noise in AmebaPro2 FreeRTOS SDK. Please find the attached files for testing, kindly replace the AudioStream.cpp and AudioStream.h in your Arduino SDK, then compile audio_ns_test.ino to see if the background noise is still too loud for you. We have added setHPFc(uint8_t fc) for testing, you may set the value of fc from 0 to 7, fc ~= 5e-3 / (hpf_fc + 1) * fs.
Thank you.
hpf_0304.zip (23.0 KB)
Hi there,
No, the background noise is not getting removed
May be it should be so clear
Thank You
Hi @Pallavi_Lad ,
Regarding your flickering issue, kindly replace the attached AmebaILI9341.cpp below and change your ILI SPI frequency to 40000000.
Thank you.
#define ILI9341_SPI_FREQUENCY 40000000
AmebaILI9341.zip (2.9 KB)
Hi @Pallavi_Lad ,
Would you like to try using a digital mic or I2S mic? It might be a better solution for the ambient noise issue. The Arduino SDK can support digital mic currently, and I2S mic will be supported soon.
Thank you.
Hi there,
Even this is not working still there is flicker is happening. I could get the confirmation that does the flicker will go or not ?
Since I am trying from past one month so plz give me confirmation
Thank you
Hi @Pallavi_Lad ,
Would you like to share a video of the flickering issue that you encounter? I have tested it on my end and I could not see any flickering after replacing with the new AmebaILI9341.cpp
Thank you.
Hello , Please I would know the producer to do this and this is a header file right .
Please correct if I am wrong
Thank you
