Reputation: 4914
I am trying to play a simple PCM file on iOS but couldn't wrap my head around AudioStreamBasicDescription
and this link does not provide enough information.
I get this values from terminal
afinfo BlameItOnTheNight.wav
File: BlameItOnTheNight.wav
File type ID: WAVE
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer
no channel layout.
estimated duration: 9.938141 sec
audio bytes: 1753088
audio packets: 438272
bit rate: 1411200 bits per second
packet size upper bound: 4
maximum packet size: 4
audio data file offset: 44
optimized
source bit depth: I16
----
Then I choose values in code
- (void)setupAudioFormat:(AudioStreamBasicDescription*)format
{
format->mSampleRate = 44100.0;
format->mFormatID = kAudioFormatLinearPCM;
format->mFramesPerPacket = 1;
format->mChannelsPerFrame = 2;
format->mBytesPerFrame = format->mChannelsPerFrame * sizeof(Float32);
format->mBytesPerPacket = format->mFramesPerPacket * format->mBytesPerFrame;
format->mBitsPerChannel = sizeof(Float32) * 8;
format->mReserved = 0;
format->mFormatFlags = kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked;
}
Audio plays really fast.
Whats the correct way the calculate this values based on actual audio file?
Upvotes: 3
Views: 3980
Reputation: 4914
when I changed the values I was getting following error.
error for object 0x7fba72c50db8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
then finally I figured out that my AudioStreamBasicDescription
bitsperchannel
values was not correct also the buffer size was not enough.
So first I have changed the values to
- (void)setupAudioFormat:(AudioStreamBasicDescription*)format
{
format->mSampleRate = 44100.0;
format->mFormatID = kAudioFormatLinearPCM;
format->mFramesPerPacket = 1; //For uncompressed audio, the value is 1. For variable bit-rate formats, the value is a larger fixed number, such as 1024 for AAC
format->mChannelsPerFrame = 2;
format->mBytesPerFrame = format->mChannelsPerFrame * 2;
format->mBytesPerPacket = format->mFramesPerPacket * format->mBytesPerFrame;
format->mBitsPerChannel = 16;
format->mReserved = 0;
format->mFormatFlags = kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kLinearPCMFormatFlagIsPacked;
}
then when I allocate buffer I increased the size
// Allocate and prime playback buffers
playState.playing = true;
for (int i = 0; i < NUM_BUFFERS && playState.playing; i++)
{
AudioQueueAllocateBuffer(playState.queue, 32000, &playState.buffers[i]);
AudioOutputCallback(&playState, playState.queue, playState.buffers[i]);
}
In my original code it was set to 8000
, now changing it to 32000 solves the problem.
Upvotes: 4