X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_coreaudio.c;h=ce8fff5bcf7d02073d025d78cc6b9bb20c929f9d;hp=c9f6c1e7635dfcc8c84650d47aed5c08b6463caa;hb=413d0b4aa169829f1c464b2bcde781972af138a2;hpb=46beb90e5efa3ac39c72ec78d11a76adf2f71331 diff --git a/snd_coreaudio.c b/snd_coreaudio.c index c9f6c1e7..ce8fff5b 100644 --- a/snd_coreaudio.c +++ b/snd_coreaudio.c @@ -37,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; /* @@ -53,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; @@ -100,7 +114,7 @@ static OSStatus audioDeviceIOProc(AudioDeviceID inDevice, snd_renderbuffer->startframe += frameCount; - // Unlock the snd_renderbuffer + // unlock the mutex now SndSys_UnlockRenderBuffer(); } @@ -110,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])); } @@ -138,6 +152,7 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) return true; Con_Printf("Initializing CoreAudio...\n"); + snd_threaded = false; if(requested->width != 2) { @@ -189,7 +204,7 @@ 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); @@ -200,18 +215,18 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) return false; } - Con_DPrint (" Hardware format:\n"); - Con_DPrintf(" %5d mSampleRate\n", (unsigned int)streamDesc.mSampleRate); - Con_DPrintf(" %c%c%c%c mFormatID\n", + 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_DPrintf(" %5u mBytesPerPacket\n", (unsigned int)streamDesc.mBytesPerPacket); - Con_DPrintf(" %5u mFramesPerPacket\n", (unsigned int)streamDesc.mFramesPerPacket); - Con_DPrintf(" %5u mBytesPerFrame\n", (unsigned int)streamDesc.mBytesPerFrame); - Con_DPrintf(" %5u mChannelsPerFrame\n", (unsigned int)streamDesc.mChannelsPerFrame); - Con_DPrintf(" %5u mBitsPerChannel\n", (unsigned int)streamDesc.mBitsPerChannel); + 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); // Suggest proper settings if they differ if (requested->channels != streamDesc.mChannelsPerFrame || requested->speed != streamDesc.mSampleRate) @@ -225,45 +240,54 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) return false; } - 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", (int)status); - return false; - } - - // We haven't sent any sample frames yet - coreaudiotime = 0; - - if (pthread_mutex_init(&coreaudio_mutex, NULL) != 0) - { - Con_Print("CoreAudio: can't create pthread mutex\n"); - AudioDeviceRemoveIOProc(outputDeviceID, audioDeviceIOProc); - 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", (int)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; } @@ -304,6 +328,10 @@ void SndSys_Shutdown(void) Mem_Free(snd_renderbuffer); snd_renderbuffer = NULL; } + + if (mixbuffer != NULL) + Mem_Free(mixbuffer); + mixbuffer = NULL; } @@ -355,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 }