]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_coreaudio.c
a third console picture layer. NOW we should be able to do about anything remotely...
[xonotic/darkplaces.git] / snd_coreaudio.c
index e3a934c3941946dfeda0f9643ac38c2445d940f7..ce8fff5bcf7d02073d025d78cc6b9bb20c929f9d 100644 (file)
@@ -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)
        {
@@ -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
 }