X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_coreaudio.c;h=ce8fff5bcf7d02073d025d78cc6b9bb20c929f9d;hp=92f4c0641c5b3359fc10b9bcd4211cfce05da320;hb=221a6cb74c3a3b30b9e60247d6e42d7a6fcdebf0;hpb=63546610a4fc30187da731dbe6dcb4ab734c3a4f diff --git a/snd_coreaudio.c b/snd_coreaudio.c index 92f4c064..ce8fff5b 100644 --- a/snd_coreaudio.c +++ b/snd_coreaudio.c @@ -20,12 +20,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ +#include "quakedef.h" + #include #include #include -#include "quakedef.h" #include "snd_main.h" @@ -36,6 +37,7 @@ static unsigned int coreaudiotime = 0; // based on the number of chunks submitt static qboolean s_isRunning = false; static pthread_mutex_t coreaudio_mutex; static AudioDeviceID outputDeviceID = kAudioDeviceUnknown; +static short *mixbuffer = NULL; /* @@ -52,19 +54,32 @@ static OSStatus audioDeviceIOProc(AudioDeviceID inDevice, void *inClientData) { float *outBuffer; - unsigned int frameCount, factor; + unsigned int frameCount, factor, sampleIndex; + float scale = 1.0f / SHRT_MAX; outBuffer = (float*)outOutputData->mBuffers[0].mData; factor = snd_renderbuffer->format.channels * snd_renderbuffer->format.width; frameCount = 0; + if (snd_blocked) + scale = 0; // Lock the snd_renderbuffer if (SndSys_LockRenderBuffer()) { - unsigned int maxFrames, sampleIndex, sampleCount; + unsigned int maxFrames, sampleCount; unsigned int startOffset, endOffset; const short *samples; - const float scale = 1.0f / SHRT_MAX; + + if (snd_usethreadedmixing) + { + S_MixToBuffer(mixbuffer, submissionChunk); + sampleCount = submissionChunk * snd_renderbuffer->format.channels; + for (sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) + outBuffer[sampleIndex] = mixbuffer[sampleIndex] * scale; + // unlock the mutex now + SndSys_UnlockRenderBuffer(); + return 0; + } // Transfert up to a chunk of sample frames from snd_renderbuffer to outBuffer maxFrames = snd_renderbuffer->endframe - snd_renderbuffer->startframe; @@ -99,7 +114,7 @@ static OSStatus audioDeviceIOProc(AudioDeviceID inDevice, snd_renderbuffer->startframe += frameCount; - // Unlock the snd_renderbuffer + // unlock the mutex now SndSys_UnlockRenderBuffer(); } @@ -109,8 +124,8 @@ static OSStatus audioDeviceIOProc(AudioDeviceID inDevice, unsigned int missingFrames; missingFrames = submissionChunk - frameCount; - if (developer.integer >= 1000 && vid_activewindow) - Con_Printf("audioDeviceIOProc: %u sample frames missing\n", missingFrames); + if (developer_insane.integer && vid_activewindow) + Con_DPrintf("audioDeviceIOProc: %u sample frames missing\n", missingFrames); memset(&outBuffer[frameCount * snd_renderbuffer->format.channels], 0, missingFrames * sizeof(outBuffer[0])); } @@ -137,26 +152,15 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) return true; Con_Printf("Initializing CoreAudio...\n"); + snd_threaded = false; - if (suggested != NULL) - memcpy (suggested, requested, sizeof (suggested)); - - // Get the device status and suggest any appropriate changes to format - propertySize = sizeof(streamDesc); - status = AudioDeviceGetProperty(outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &streamDesc); - if (status) + if(requested->width != 2) { - Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when getting kAudioDevicePropertyStreamFormat\n", status); - return false; - } - // Suggest proper settings if they differ - if (requested.channels != streamDesc.mChannelsPerFrame || requested.speed != streamDesc.mSampleRate || requested.width != streamDesc.mBitsPerChannel/8) - { - if (suggested != NULL) + // we can only do 16bit per sample for now + if(suggested != NULL) { - suggested->channels = streamDesc.mChannelsPerFrame; - suggested->speed = streamDesc.mSampleRate; - suggested->width = streamDesc.mBitsPerChannel/8; + memcpy (suggested, requested, sizeof (*suggested)); + suggested->width = 2; } return false; } @@ -166,7 +170,7 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &outputDeviceID); if (status) { - Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when getting kAudioHardwarePropertyDefaultOutputDevice\n", status); + Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when getting kAudioHardwarePropertyDefaultOutputDevice\n", (int)status); return false; } if (outputDeviceID == kAudioDeviceUnknown) @@ -181,7 +185,7 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) status = AudioDeviceSetProperty(outputDeviceID, NULL, 0, false, kAudioDevicePropertyBufferSize, propertySize, &bufferByteCount); if (status) { - Con_Printf("CoreAudio: AudioDeviceSetProperty() returned %d when setting kAudioDevicePropertyBufferSize to %d\n", status, CHUNK_SIZE); + Con_Printf("CoreAudio: AudioDeviceSetProperty() returned %d when setting kAudioDevicePropertyBufferSize to %d\n", (int)status, CHUNK_SIZE); return false; } @@ -189,7 +193,7 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) status = AudioDeviceGetProperty(outputDeviceID, 0, false, kAudioDevicePropertyBufferSize, &propertySize, &bufferByteCount); if (status) { - Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when setting kAudioDevicePropertyBufferSize\n", status); + Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when setting kAudioDevicePropertyBufferSize\n", (int)status); return false; } @@ -200,68 +204,90 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) return false; } submissionChunk /= requested->channels; - Con_DPrintf(" Chunk size = %d sample frames\n", submissionChunk); + Con_Printf(" Chunk size = %d sample frames\n", submissionChunk); // Print out the device status propertySize = sizeof(streamDesc); status = AudioDeviceGetProperty(outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &streamDesc); if (status) { - Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when getting kAudioDevicePropertyStreamFormat\n", status); - return false; - } - Con_DPrint (" Hardware format:\n"); - Con_DPrintf(" %5d mSampleRate\n", (unsigned int)streamDesc.mSampleRate); - Con_DPrintf(" %c%c%c%c mFormatID\n", - (streamDesc.mFormatID & 0xff000000) >> 24, - (streamDesc.mFormatID & 0x00ff0000) >> 16, - (streamDesc.mFormatID & 0x0000ff00) >> 8, - (streamDesc.mFormatID & 0x000000ff) >> 0); - Con_DPrintf(" %5d mBytesPerPacket\n", streamDesc.mBytesPerPacket); - Con_DPrintf(" %5d mFramesPerPacket\n", streamDesc.mFramesPerPacket); - Con_DPrintf(" %5d mBytesPerFrame\n", streamDesc.mBytesPerFrame); - Con_DPrintf(" %5d mChannelsPerFrame\n", streamDesc.mChannelsPerFrame); - Con_DPrintf(" %5d mBitsPerChannel\n", streamDesc.mBitsPerChannel); - - if(streamDesc.mFormatID != kAudioFormatLinearPCM) - { - Con_Print("CoreAudio: Default audio device doesn't support linear PCM!\n"); - return false; - } - - // Add the callback function - status = AudioDeviceAddIOProc(outputDeviceID, audioDeviceIOProc, NULL); - if (status) - { - Con_Printf("CoreAudio: AudioDeviceAddIOProc() returned %d\n", status); + Con_Printf("CoreAudio: AudioDeviceGetProperty() returned %d when getting kAudioDevicePropertyStreamFormat\n", (int)status); return false; } - // We haven't sent any sample frames yet - coreaudiotime = 0; + Con_Print (" Hardware format:\n"); + Con_Printf(" %5d mSampleRate\n", (unsigned int)streamDesc.mSampleRate); + Con_Printf(" %c%c%c%c mFormatID\n", + (char)(streamDesc.mFormatID >> 24), + (char)(streamDesc.mFormatID >> 16), + (char)(streamDesc.mFormatID >> 8), + (char)(streamDesc.mFormatID >> 0)); + Con_Printf(" %5u mBytesPerPacket\n", (unsigned int)streamDesc.mBytesPerPacket); + Con_Printf(" %5u mFramesPerPacket\n", (unsigned int)streamDesc.mFramesPerPacket); + Con_Printf(" %5u mBytesPerFrame\n", (unsigned int)streamDesc.mBytesPerFrame); + Con_Printf(" %5u mChannelsPerFrame\n", (unsigned int)streamDesc.mChannelsPerFrame); + Con_Printf(" %5u mBitsPerChannel\n", (unsigned int)streamDesc.mBitsPerChannel); - if (pthread_mutex_init(&coreaudio_mutex, NULL) != 0) + // Suggest proper settings if they differ + if (requested->channels != streamDesc.mChannelsPerFrame || requested->speed != streamDesc.mSampleRate) { - Con_Print("CoreAudio: can't create pthread mutex\n"); - AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc); + if (suggested != NULL) + { + memcpy (suggested, requested, sizeof (*suggested)); + suggested->channels = streamDesc.mChannelsPerFrame; + suggested->speed = streamDesc.mSampleRate; + } return false; } - snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL); - - // Start sound running - status = AudioDeviceStart(outputDeviceID, audioDeviceIOProc); - if (status) + if(streamDesc.mFormatID == kAudioFormatLinearPCM) { - Con_Printf("CoreAudio: AudioDeviceStart() returned %d\n", status); - pthread_mutex_destroy(&coreaudio_mutex); - AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc); - return false; + // Add the callback function + status = AudioDeviceAddIOProc(outputDeviceID, audioDeviceIOProc, NULL); + if (!status) + { + // We haven't sent any sample frames yet + coreaudiotime = 0; + if (pthread_mutex_init(&coreaudio_mutex, NULL) == 0) + { + if ((snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL))) + { + if ((mixbuffer = Mem_Alloc(snd_mempool, CHUNK_SIZE * sizeof(*mixbuffer) * requested->channels))) + { + // Start sound running + status = AudioDeviceStart(outputDeviceID, audioDeviceIOProc); + if (!status) + { + s_isRunning = true; + snd_threaded = true; + Con_Print(" Initialization successful\n"); + return true; + } + else + Con_Printf("CoreAudio: AudioDeviceStart() returned %d\n", (int)status); + Mem_Free(mixbuffer); + mixbuffer = NULL; + } + else + Con_Print("CoreAudio: can't allocate memory for mixbuffer\n"); + Mem_Free(snd_renderbuffer->ring); + Mem_Free(snd_renderbuffer); + snd_renderbuffer = NULL; + } + else + Con_Print("CoreAudio: can't allocate memory for ringbuffer\n"); + pthread_mutex_destroy(&coreaudio_mutex); + } + else + Con_Print("CoreAudio: can't create pthread mutex\n"); + AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc); + } + else + Con_Printf("CoreAudio: AudioDeviceAddIOProc() returned %d\n", (int)status); } - s_isRunning = true; - - Con_Print(" Initialization successful\n"); - return true; + else + Con_Print("CoreAudio: Default audio device doesn't support linear PCM!\n"); + return false; } @@ -282,7 +308,7 @@ void SndSys_Shutdown(void) status = AudioDeviceStop(outputDeviceID, audioDeviceIOProc); if (status) { - Con_Printf("AudioDeviceStop: returned %d\n", status); + Con_Printf("AudioDeviceStop: returned %d\n", (int)status); return; } s_isRunning = false; @@ -292,7 +318,7 @@ void SndSys_Shutdown(void) status = AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc); if (status) { - Con_Printf("AudioDeviceRemoveIOProc: returned %d\n", status); + Con_Printf("AudioDeviceRemoveIOProc: returned %d\n", (int)status); return; } @@ -302,6 +328,10 @@ void SndSys_Shutdown(void) Mem_Free(snd_renderbuffer); snd_renderbuffer = NULL; } + + if (mixbuffer != NULL) + Mem_Free(mixbuffer); + mixbuffer = NULL; } @@ -353,5 +383,17 @@ Release the exclusive lock on "snd_renderbuffer" */ void SndSys_UnlockRenderBuffer (void) { - pthread_mutex_unlock(&coreaudio_mutex); + pthread_mutex_unlock(&coreaudio_mutex); +} + +/* +==================== +SndSys_SendKeyEvents + +Send keyboard events originating from the sound system (e.g. MIDI) +==================== +*/ +void SndSys_SendKeyEvents(void) +{ + // not supported }