inquiry about audio sample, confused of recorder samples
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
inquiry about audio sample, confused of recorder samples
Good day fellas,
audio programming is interesting and i am a bit on starting to learn some recording and playing and manipulating sample audio samples
I would like to ask some comments or suggestion or answer to my queries.
I have a recorder app, the settings for the recorder is 96000 sampling rate 8 bit wave pcm...mono
first, I am confused, I am getting values like values from -128 to + 127...the data holder is signed char...I am expecting signed waves with 0 in between...
second, I want to try also to filter the recorded value using bandpass filter(http://www.exstrom.com/journal/sigproc/)...
does this sample values that i received has no problem with when I pass it to the filter? or do i need to convert the values?
because after the applying the bandpass filter, it resulted to weird data.
and maybe you have also a quick helpful reference in using bandpass filter with easy C sample code...DSP is a big thing for me, i am newbie here..
http://www.exstrom.com/journal/sigproc/ <<---does this link helpful for bandpass filter?
audio programming is interesting and i am a bit on starting to learn some recording and playing and manipulating sample audio samples
I would like to ask some comments or suggestion or answer to my queries.
I have a recorder app, the settings for the recorder is 96000 sampling rate 8 bit wave pcm...mono
first, I am confused, I am getting values like values from -128 to + 127...the data holder is signed char...I am expecting signed waves with 0 in between...
second, I want to try also to filter the recorded value using bandpass filter(http://www.exstrom.com/journal/sigproc/)...
does this sample values that i received has no problem with when I pass it to the filter? or do i need to convert the values?
because after the applying the bandpass filter, it resulted to weird data.
and maybe you have also a quick helpful reference in using bandpass filter with easy C sample code...DSP is a big thing for me, i am newbie here..
http://www.exstrom.com/journal/sigproc/ <<---does this link helpful for bandpass filter?
Re: inquiry about audio sample, confused of recorder samples
Signed 8 bit audio should have values between +127 and -128 (see here: http://en.wikipedia.org/wiki/Signed_num ... complement )tongyong wrote: I am getting values like values from -128 to + 127...the data holder is signed char...I am expecting signed waves with 0 in between...
For processing in Audacity these values would be converted to a range of +/- 1 in 32-bit float format.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
Re: inquiry about audio sample, confused of recorder samples
thanks steve...so i need to convert it to -1 to 1 range
my sample data charSamples[ARRAY_SIZE] an array of signed chars
which one i am using below?do I need to subtract 128 from the sample?
floatSamples = (charSamples-128)/32768.0
or
floatSamples = (float)charSamples/32768.0
another question:
is the following code okay for converting float to signed 8 bit? because after
for (int i = 0; i <SampleCount; i++)
charTo = (byte)(128 + ((byte)(floatFrom*(127.0))));
my sample data charSamples[ARRAY_SIZE] an array of signed chars
which one i am using below?do I need to subtract 128 from the sample?
floatSamples = (charSamples-128)/32768.0
or
floatSamples = (float)charSamples/32768.0
another question:
is the following code okay for converting float to signed 8 bit? because after
for (int i = 0; i <SampleCount; i++)
charTo = (byte)(128 + ((byte)(floatFrom*(127.0))));
Re: inquiry about audio sample, confused of recorder samples
I've no idea if you need to converttongyong wrote:so i need to convert it to -1 to 1 range
If you do convert to 32-bit and then convert back to 8 bit integer, you should really use dither to randomize quantize errors when down-sampling from 32 to 8 bit. On the other hand, if you keep the data in integer format then it might simplify the programming, but there will be significant rounding errors.
I'm afraid I can't help with the programming aspects as I'm not a programmer. I'll see if I can get someone that knows about programming to comment.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
Re: inquiry about audio sample, confused of recorder samples
steve wrote:Signed 8 bit audio should have values between +127 and -128tongyong wrote: I am getting values like values from -128 to + 127...the data holder is signed char...I am expecting signed waves with 0 in between...
For processing in Audacity these values would be converted to a range of +/- 1 in 32-bit float format.
tongyong wrote:i need to convert it to -1 to 1 range
my sample data charSamples[ARRAY_SIZE] an array of signed chars
which one i am using below?do I need to subtract 128 from the sample?
floatSamples = (charSamples-128)/32768.0
or
floatSamples = (float)charSamples/32768.0
My disclaimer: while I am a programmer with some knowledge of Audacity, my forte is GUI and interface design with a bit of math. I think your math is wrong so let me try to explain my (limited) understanding...
As Steve says, signed 8-bit data spreads out between -128 & +127 inclusive (note because of the zero it is not -128 through +128).
-128........-1....0....+1.......+127
we need to map those values to signed floats between -1.00 and +1.00 inclusive (note because of zero there will not be a one-to-one ratio that is the same for both positive and negative numbers):
-1.00.............0..............-1.00
So, we will need two*three (6) "formulas" -- one set for 8-bit to float and one set for float to 8-bit; thus two each of:
one to deal with negative values
one trivial one to deal with zero so we don't see any divide-by-zero errors
and one for positive
So we have a compound conditional:
Code: Select all
if (value == 0) {
do the zero formula
}
else if (value < 0) {
do the less-than-zero formula
}
else {
do the greater-than-zero formula
}
Code: Select all
if (aChar == 0) {
outFloat = 0f;
}
and
if (outFloat == 0f) {
aChar = 0;
}
Code: Select all
if (aChar > 0) { //positive char to positive float
outFloat = ;
}
and
if (aChar < 0) {//negative char to float
outFloat = ;
}
if (outFloat > 0) { //positive float to positive char
aChar = ;
}
and
if (outFloat < 0) {//negative float to char
aChar = ;
}
-4 = -1.00
-3 = -0.75
-2 = -0.50
-1 = -0.25
0 = 0
1 = +0.33333333...
2 = +0.66666666...
3 = +1.00
As you can see, ignoring the sign, the mapping of +2 and -2 are vastly different and the reason is obvious. The general formula for negative is floatValue equals (charValue divided by the number of negative integers)--in this case 4, in the real case MIN(signed 8-bit) which is 128. For positive use the same general idea but we need to use MAX(signed 8-bit) which is one integer smaller.
Mapping the same floats:
-1.00 = -4
-0.75 = -3
-0.50 = -2
-0.33 = -1
0 = 0
+0.33 = 1
+0.66 = 2
+1.00 = 3
The general negative case here is charValue equals (floatValue times the number of negative integers) and for positive charValue equals (floatValue times the number of positive integers); no divide-by-zero problem but zero still needs to be dealt with.
Code: Select all
char-to-float (where a divide-by-zero error could occur):
if (aChar < 0) {//negative char
outFloat = aChar / 128;//note, need much better code here, bad rounding & variable promotion
}
else if (aChar > 0) {//positive char
outFloat = aChar / 127;note, need much better code here...
}
else{// (aChar == 0)
outFloat = 0f;//good enough code
}
and for float-to-char
if (outFloat <= 0f) {//less than or equal to zero
aChar = outFloat * 128;//note, need much better code here, bad rounding & variable promotion
}
else {
aChar = outFloat * 127;//note, need much better code here...
}
In the above the note is talking about how the computer deals with the division--since both are integers it will be done using integer math and rounding routines. What we need to do is promote everything to the highest resolution variable possible before doing the math then use the proper rounding formula:
Code: Select all
if (aChar < 0) {//negative char
float tempChar = (float)aChar;//promote char to float
float intermediateValue = tempChar / 128.0f;//note we promote 128 to a float
outFloat = round(intermediateValue);//see round() below;
}
float round(float r) {//symmetrical round
return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}
In the above the note is talking about the same thing. The extension of the other simplified formulas is left to the reader<grin> !
tongyong wrote: another question:
is the following code okay for converting float to signed 8 bit? because after
for (int i = 0; i <SampleCount; i++)
charTo = (byte)(128 + ((byte)(floatFrom*(127.0))));
steve wrote: I'm afraid I can't help with the programming aspects as I'm not a programmer. I'll see if I can get someone that knows about programming to comment.
Don't let Steve Steve fool you, he is a great programmer with lots of released code. What he means to say is that he does not program in a C-style language (C++ etc.), he programs in Nyquist a highly specialized language for writing audio related plug-ins.
As to your formula see my answer above.
Re: inquiry about audio sample, confused of recorder samples
From a PM:
The solution I proposed could be expanded to deal with a return of +1.0f:
That is why my disclaimer <grin> ! I can do the math but have no real understanding of the audio standards. From what I can see, +1.0 is valid -- why does Audacity ban it?steve wrote: There may be a![]()
I don't know if there are any established standards regards converting float format audio to integer audio but in Audacity there is no +1.0 for integer formats.![]()
There is a note in the libsndfile documentation about this: http://www.mega-nerd.com/libsndfile/FAQ.html#Q010
The solution I proposed could be expanded to deal with a return of +1.0f:
Code: Select all
char-to-float (where a divide-by-zero error could occur):
else if (aChar > 0) {//positive char
outFloat = aChar / 127;note, need much better code here...
if (aChar == 127) {//would yield +1.0f which is unwanted
outFloat = outFloat - MIN(float);// (MIN(float) may not be defined; bitshift is not implemented for floats as far as I know but would be a better theoretical choice)
}
}
Re: inquiry about audio sample, confused of recorder samples
I believe most DSP algorithms assume floating point.
Actually, 8-bit WAV files use unsigned integers (0-255). Silence is 128. So, you generally have to subtract 128 and convert to signed before doing any conversions or before trying to visualize the waveform. Here is a reference. (Look under "Notes".) 16 bit WAV files use signed integers.
* I wasn't sure if silence was 127 or 128, so I created an 8-bit silent file and looked at it with a hex editor. It was full of 80 hex (128 decimal).
Actually, 8-bit WAV files use unsigned integers (0-255). Silence is 128. So, you generally have to subtract 128 and convert to signed before doing any conversions or before trying to visualize the waveform. Here is a reference. (Look under "Notes".) 16 bit WAV files use signed integers.
Maybe because there is +1, but no "point zero" in integers????...there is no +1.0 for integer formats.
* I wasn't sure if silence was 127 or 128, so I created an 8-bit silent file and looked at it with a hex editor. It was full of 80 hex (128 decimal).
Last edited by DVDdoug on Tue Nov 22, 2011 1:02 am, edited 1 time in total.
Re: inquiry about audio sample, confused of recorder samples
I totally agree that is what an 8 bit RIFF file should be, but I'm confused by the original post:DVDdoug wrote:Actually, 8-bit WAV files use unsigned integers (0-255). 16 bit WAV files use signed integers. Silence is 128. Here is a reference.
What is this "recorder app,"?tongyong wrote:I have a recorder app, the settings for the recorder is 96000 sampling rate 8 bit wave pcm...mono
first, I am confused, I am getting values like values from -128 to + 127...the data holder is signed char...
Recording at 96 kHz and 8 bit is a very odd combination for audio, and even more so if it is signed 8-bit data.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
Re: inquiry about audio sample, confused of recorder samples
I think DVDDoug has more knowledge on the topic than I and I will happily bow to his knowledge! I was asked a specific mathematical question – how to do something in a C++ program. I was very careful to preface my reply with a disclaimer which I will now paraphrase – I am a "pretty good" GUI/interface programmer and a fair mathematician but I know next to nothing about audio formats. I suspect that my answer was in-depth enough to explain the process and a reasonably intelligent programmer can plug in the appropriate MIN and MAX values for the non-float variables and adopt my code as appropriate.
Re: inquiry about audio sample, confused of recorder samples
Thank you very much, I do now understand a little bit.
@ steve: yeah, its a little bit odd but its a good start for me.
@ DVDdoug: thanks for the link
@Edgar: That's so detailed..thank you very much.
One more question:
Do playback have the same scenario?
That we have to fed a 8bit signed(+127 to -128) also to the audio?
because I created a sine wave tone (from this formula: Amplitude*sin(2*Pi*Freq*Time)...Amplitude used was 120
currently what i did was, I cast the output of the formula to integer and added 127; and kinda have a weird unwilling noise of the tone.
@ steve: yeah, its a little bit odd but its a good start for me.
@ DVDdoug: thanks for the link
@Edgar: That's so detailed..thank you very much.
One more question:
Do playback have the same scenario?
That we have to fed a 8bit signed(+127 to -128) also to the audio?
because I created a sine wave tone (from this formula: Amplitude*sin(2*Pi*Freq*Time)...Amplitude used was 120
currently what i did was, I cast the output of the formula to integer and added 127; and kinda have a weird unwilling noise of the tone.