MacOS CoreAudio buffer playback produces annoying noise between correct sound. I'm interested to play valid .wav data though the buffer. Why I'm playing a .wav? It has valid data. What I'm trying to achieve is to understand how to write correctly to the sound buffer. I'm porting a music engine to MacOS ....
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#include <AudioToolbox/AudioToolbox.h>
FILE *fp;
typedef struct TwavHeader{
char RIFF[4];
uint32_t RIFFChunkSize;
char WAVE[4];
char fmt[4];
uint32_t Subchunk1Size;
uint16_t AudioFormat;
uint16_t NumOfChan;
uint32_t SamplesPerSec;
uint32_t bytesPerSec;
uint16_t blockAlign;
uint16_t bitsPerSample;
char Subchunk2ID[4];
uint32_t Subchunk2Size;
}TwavHeader;
typedef struct SoundState {
bool done;
}SoundState;
void auCallback(void *inUserData, AudioQueueRef queue, AudioQueueBufferRef buffer) {
buffer->mAudioDataByteSize = 1024*4;
int numToRead = buffer->mAudioDataByteSize / sizeof(float) * 2;
void *p = malloc(numToRead);
fread(p, numToRead,1,fp);
void *myBuf = buffer->mAudioData;
for (int i=0; i < numToRead / 2; i++) {
uint16_t w = *(uint16_t *)&(p[i*sizeof(uint16_t)]);
float f = ((float)w / (float)0x8000) - 1.0;
*(float *)&(myBuf[i*sizeof(float)]) = f;
}
free(p);
AudioQueueEnqueueBuffer(queue, buffer, 0, 0);
}
void checkError(OSStatus error){
if (error != noErr) {
printf("Error: %d", error);
exit(error);
}
}
int main(int argc, const char * argv[]) {
printf("START\n");
TwavHeader theHeader;
fp = fopen("/Users/kirillkranz/Documents/mytralala-code/CoreAudioTest/unreal.wav", "r");
fread(&theHeader, sizeof(TwavHeader),1,fp);
printf("%i\n",theHeader.bitsPerSample);
AudioStreamBasicDescription auDesc = {};
auDesc.mSampleRate = theHeader.SamplesPerSec;
auDesc.mFormatID = kAudioFormatLinearPCM;
auDesc.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
auDesc.mBytesPerPacket = 8;
auDesc.mFramesPerPacket = 1;
auDesc.mBytesPerFrame = 8;
auDesc.mChannelsPerFrame = 2;
auDesc.mBitsPerChannel = 32;
AudioQueueRef auQueue = 0;
AudioQueueBufferRef auBuffers[2] ={};
// our persistent state for sound playback
SoundState soundState= {};
soundState.done=false;
OSStatus err;
// most of the 0 and nullptr params here are for compressed sound formats etc.
err = AudioQueueNewOutput(&auDesc, &auCallback, &soundState, 0, 0, 0, &auQueue);
checkError(err);
// generate buffers holding at most 1/16th of a second of data
uint32_t bufferSize = auDesc.mBytesPerFrame * (auDesc.mSampleRate / 16);
err = AudioQueueAllocateBuffer(auQueue, bufferSize, &(auBuffers[0]));
checkError(err);
err = AudioQueueAllocateBuffer(auQueue, bufferSize, &(auBuffers[1]));
checkError(err);
// prime the buffers
auCallback(&soundState, auQueue, auBuffers[0]);
auCallback(&soundState, auQueue, auBuffers[1]);
// enqueue for playing
AudioQueueEnqueueBuffer(auQueue, auBuffers[0], 0, 0);
AudioQueueEnqueueBuffer(auQueue, auBuffers[1], 0, 0);
// go!
AudioQueueStart(auQueue, 0);
char rxChar[10]; scanf( "%s", &rxChar);
printf("FINISH");
fclose(fp);
// be nice even it doesn't really matter at this point
if (auQueue)
AudioQueueDispose(auQueue, true);
}
what do I do wrong?