I want to detect silence in audio streaming. I've been following lot of answers from any website and i feel like know how to do that. but i doubt i'm on the right path coz the result doesn't seems right.

The stream is in mp3 format 16 bit 22050 hz, the data stream divided into small packets. So every packet received I'll check the data if its a header or not to build complete chunk of mp3. Every complete packets(mp3 chunk) will be decoded into PCM. the PCM data consist of signed value between 0-255. i will split every PCM data into 1.16 seconds of audio to detect silence in that duration. I've read some answer to scale the signals to make it between -1 and 1 for further processing.

My first try is calculating RMS. the PCM data will be splited into 20 miliseconds and calculated to RMS for each number of samples (samples=PCM.length*0.02). Then changes the RMS result to dB with 20*log(rms)/log(10). The result is not as i expected. The more silence in the audio, i get less dB rate (-20dB to -30dB) and get (-50dB to -70dB) for more noise in audio. Then i try to compare it in chart but it doesn't really help at all. I think the result is somehow wrong.

My second try is using FFT. The scaled signals from previous data added with padding to make it 2^n length. The padding used to make signals can be calculated with FFT. After i got the FFT result, then i do A-weighting. I can see some similarity in noise audio. The silence audio gives random chart that can't be compared with noise audio. So i decided to use noise to compare with every a-weighting result. First i try to compare it with calculating DTW of those signals and make the threshold is not more than 5k in differences, but sometimes i getting audio error(the accuracy is around 90%). Then i try compare it with another method using correlation ifft(fft(noise) * fft(test)), but i don't know how to use it. I've been comparing same 4 signals and the result doesn't showing any number 1 in that list (the highest is 0.625)

could you tell me what my mistake is? i really confused where my mistake is. actually i want the result like ffmpeg RMS level but i didn't get the same result with ffmpeg in my first try. i can't use ffmpeg library coz my bos ask me to calculate it from memory which is pipe in and pipe out. i've try that and it seems ffmpeg can't be use for that scenario. and tell me if you need some sample of error. I'll provide you that. thanks


the PCM data consist of signed value between 0-255.

That seems to be your problem. A 16 bit MP3 file decodes into signed integer values of -32768 to +32767. Perhaps you are looking at bytes and not at samples ?

  • $\begingroup$ Big vs little endian has perplexed more than a few people as well $\endgroup$ – Stanley Pawlukiewicz Jan 22 at 1:54
  • $\begingroup$ ah, thanks, i know what my mistake is. you're right. i calculate a byte instead 2 bytes. CMIIW, the PCM is always in little endian ( i read in somewhere)? $\endgroup$ – Hilman Nihri Jan 22 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.