Reputation: 21
I have tried to change the volume of a PCM wave file in C: 2 channel, Sample Rate: 22050 Hz. 24 bits per sample.
But when I do, I get lots of distortion, I tried a way that I have found among the answers to Reduce the volume of a Wav audio file using C. I also did a simple divide by 2 of the 24 bit data, but all the things I tried resulted in a very distorted signal (though volume goes down).
When I reduce volume by -6dB in audacity and stream the new wav to my I2S amplifier, then it plays the wav in perfect quality and at a low volume. So audacity converts the samples perfectly.. But how do they do this?
I must be doing something wrong in my software but I can't figure out what.
Following code fills a DMA buffer with 100% volume data:
buffer[i] = ((uint32_t)b2 << 16) | ((uint32_t)b1 << 8) | ((uint32_t)b0);
With this code I would expect volume will be less, but it only gets very distorted:
int32_t temp;
temp = (int32_t)((uint32_t)b2 << 16) | ((uint32_t)b1 << 8) | ((uint32_t)b0);
buffer[i] = (uint32_t)(temp /2);
Any idea why the distortion happens?
I also have tried to figure out how the data is stored, therefore I have exported the first 2 samples out of audacity, and 10 samples printed by my firmware (firmware bytes are verified as correctly with viewing the wav file with a hex viewer.
000000h,FFFEFEh,FFFF01h,000002h,FFFEFEh,FFFEFEh,000002h,000002h,FFFFFDh,FFFFFFh,FFFF04h,000000h,FFFFFDh,000000h,000002h,FFFFFFh,FFFF02h,FFFEFFh,FFFFFEh,000003h,000002h,FFFFFDh,FFFEFEh,000002h,FFFF01h,FFFFFFh,FFFFFFh,000000h,000002h,000002h,FFFFFDh,000002h,000003h,FFFFFEh,FFFFFDh,FFFF01h,000003h,000001h,FFFEFDh,FFFFFEh,FFFF03h,000002h,FFFFFDh,FFFFFFh,FFFF03h,FFFFFEh
I think it's strange to see such different values like 000000h,FFFEFEh
while the first sample shows 0 in audacity sample graph.
This is a sample export in audacity for the first 2 samples:
0.00000 0.00000
-0.00002 -0.00002
What did I get wrong?
Upvotes: 1
Views: 458
Reputation:
In order to listen to the new content of "buffer" it must be either converted back from 32 bit to 24 bit or the file format must be changed to 32bit wav. this step is not described in your question. The conversion to 32 bit should be shifted 8 bits left in order to get the sign bit in right position and use the full dynamic of 32 bit. if your host is little endian (as wave) the endianness should not be a problem.
Test the conversions in both direction before trying to alter the gain! More fine tuned gain can be obtained by using float instead of 32 bit integer.
Upvotes: 1