Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading audio buffer data with AudioQueue

I am attempting to read audio data via AudioQueue. When I do so, I can verify that the bit depth of the file is 16-bit. But when I get the actual sample data, I'm only seeing values from -128 to 128. But I'm also seeing suspicious looking interleaved data, which makes me pretty sure that I'm just not reading the data correctly.

So to begin with, I can verify that the source file is 44100, 16-bit, mono wav file.

My buffer is allocated thusly:

char *buffer= NULL;
buffer = malloc(BUFFER_SIZE);
assert(buffer);

All the relevant values are set and used in:

AudioFileReadPackets(inAudioFile,false,&bytesRead,NULL,packetNum,&numPackets,buffer);       

As a test, just so that I can see the data retrieved, I run:

for(int i=0;i<BUFFER_SIZE;i++){
  NSLog(@"%i", buffer[i]);
}

Now, I know my source file peaks all over the place, but the values I see only max at -128 and 128. Being as this is a 16-bit file, I would expect that the values would instead be -32768 to 32768.

In addition, there seems to be two patterns in the data. Here's an example of the data returned:

70
-13
31
-11
-118
-9
-15
-7
116
-4
31
-1
28
1
84
2
-123
3
-97
4
110
5
54
6
126

Now take a look at every other row starting with the second row: -13. See how it increases, not evenly, but at least smoothly? The odd-numbered rows aren't anywhere near that smooth.

My first thought would be that this is interleaved stereo data, but no, it's only one channel, so there shouldn't be any interleaving, right?

My best guess is that I'm just reading the data incorrectly, so the sample data is being spanned across two returns. Any idea how to read it correctly?

Thanks for reading through the whole question, and for any insight you can offer.

like image 994
Eric Christensen Avatar asked Aug 08 '09 05:08

Eric Christensen


1 Answers

char *buffer= NULL;

That's the reason. You're iterating over signed bytes, not 16-bit samples.

Declare the variable as holding a pointer to two-byte values instead:

SInt16 *buffer = NULL;

Then, iterate over half as many samples as bytes:

for(int i=0;i < (BUFFER_SIZE / sizeof(*buffer));i++){
  NSLog(@"%i", buffer[i]);
}

I would rename BUFFER_SIZE to BUFFER_SIZE_BYTES to clarify it.

like image 109
Peter Hosey Avatar answered Oct 26 '22 02:10

Peter Hosey