📄 audio_osx_source.cc
字号:
// verify that the number copied out is as expected. while (--l_counter >= 0) { UInt32 t_n_output_items = actual_noutput_items; d_buffers[l_counter]->dequeue ((float*) output_items[l_counter], &t_n_output_items); if (t_n_output_items != actual_noutput_items) { fprintf (stderr, "audio_osx_source::work(): " "number of available items changing " "unexpectedly; expecting %ld, got %ld.\n", actual_noutput_items, t_n_output_items); throw std::runtime_error ("audio_osx_source::work()"); } } // subtract the actual number of items removed from the buffer(s) // from the local accounting of the number of available samples d_queueSampleCount -= actual_noutput_items;#if _OSX_AU_DEBUG_ fprintf (stderr, "work2: SC = %4ld, act#OI = %4ld\n", d_queueSampleCount, actual_noutput_items);#endif // release control to allow for other processing parts to run d_internal->unlock ();#if _OSX_AU_DEBUG_ fprintf (stderr, "work3: Returning.\n");#endif return (actual_noutput_items);}OSStatusaudio_osx_source::ConverterCallback(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** ioASPD, void* inUserData){ // take current device buffers and copy them to the tail of the // input buffers the lead buffer is already there in the first // d_leadSizeFrames slots audio_osx_source* This = static_cast<audio_osx_source*>(inUserData); AudioBufferList* l_inputABL = This->d_InputBuffer; UInt32 totalInputBufferSizeBytes = ((*ioNumberDataPackets) * sizeof (float)); int counter = This->d_n_deviceChannels; ioData->mNumberBuffers = This->d_n_deviceChannels; This->d_n_ActualInputFrames = (*ioNumberDataPackets);#if _OSX_AU_DEBUG_ fprintf (stderr, "cc1: io#DP = %ld, TIBSB = %ld, #C = %d\n", *ioNumberDataPackets, totalInputBufferSizeBytes, counter);#endif while (--counter >= 0) { AudioBuffer* l_ioD_AB = &(ioData->mBuffers[counter]); l_ioD_AB->mNumberChannels = 1; l_ioD_AB->mData = (float*)(l_inputABL->mBuffers[counter].mData); l_ioD_AB->mDataByteSize = totalInputBufferSizeBytes; }#if _OSX_AU_DEBUG_ fprintf (stderr, "cc2: Returning.\n");#endif return (noErr);}OSStatusaudio_osx_source::AUInputCallback (void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData){ OSStatus err = noErr; audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon); This->d_internal->lock ();#if _OSX_AU_DEBUG_ fprintf (stderr, "cb0: in#F = %4ld, inBN = %ld, SC = %4ld\n", inNumberFrames, inBusNumber, This->d_queueSampleCount);#endif// Get the new audio data from the input device err = AudioUnitRender (This->d_InputAU, ioActionFlags, inTimeStamp, 1, //inBusNumber, inNumberFrames, This->d_InputBuffer); CheckErrorAndThrow (err, "AudioUnitRender", "audio_osx_source::AUInputCallback"); UInt32 AvailableInputFrames = inNumberFrames; This->d_n_AvailableInputFrames = inNumberFrames;// get the number of actual output frames,// either via converting the buffer or not UInt32 ActualOutputFrames; if (This->d_passThrough == true) { ActualOutputFrames = AvailableInputFrames; } else { UInt32 AvailableInputBytes = AvailableInputFrames * sizeof (float); UInt32 AvailableOutputBytes = AvailableInputBytes; UInt32 AvailableOutputFrames = AvailableOutputBytes / sizeof (float); UInt32 propertySize = sizeof (AvailableOutputBytes); err = AudioConverterGetProperty (This->d_AudioConverter, kAudioConverterPropertyCalculateOutputBufferSize, &propertySize, &AvailableOutputBytes); CheckErrorAndThrow (err, "AudioConverterGetProperty CalculateOutputBufferSize", "audio_osx_source::audio_osx_source"); AvailableOutputFrames = AvailableOutputBytes / sizeof (float);#if 0// when decimating too much, the output sounds warbly due to// fluctuating # of output frames// This should not be a surprise, but there's probably some// clever programming that could lessed the effect ...// like finding the "ideal" # of output frames, and keeping// that number constant no matter the # of input frames UInt32 l_InputBytes = AvailableOutputBytes; propertySize = sizeof (AvailableOutputBytes); err = AudioConverterGetProperty (This->d_AudioConverter, kAudioConverterPropertyCalculateInputBufferSize, &propertySize, &l_InputBytes); CheckErrorAndThrow (err, "AudioConverterGetProperty CalculateInputBufferSize", "audio_osx_source::audio_osx_source"); if (l_InputBytes < AvailableInputBytes) {// OK to zero pad the input a little AvailableOutputFrames += 1; AvailableOutputBytes = AvailableOutputFrames * sizeof (float); }#endif#if _OSX_AU_DEBUG_ fprintf (stderr, "cb1: avail: #IF = %ld, #OF = %ld\n", AvailableInputFrames, AvailableOutputFrames);#endif ActualOutputFrames = AvailableOutputFrames;// convert the data to the correct rate// on input, ActualOutputFrames is the number of available output frames err = AudioConverterFillComplexBuffer (This->d_AudioConverter, (AudioConverterComplexInputDataProc)(This->ConverterCallback), inRefCon, &ActualOutputFrames, This->d_OutputBuffer, NULL); CheckErrorAndThrow (err, "AudioConverterFillComplexBuffer", "audio_osx_source::AUInputCallback");// on output, ActualOutputFrames is the actual number of output frames#if _OSX_AU_DEBUG_ fprintf (stderr, "cb2: actual: #IF = %ld, #OF = %ld\n", This->d_n_ActualInputFrames, AvailableOutputFrames); if (This->d_n_ActualInputFrames != AvailableInputFrames) fprintf (stderr, "cb2.1: avail#IF = %ld, actual#IF = %ld\n", AvailableInputFrames, This->d_n_ActualInputFrames);#endif }// add the output frames to the buffers' queue, checking for overflow int l_counter = This->d_n_user_channels; int res = 0; while (--l_counter >= 0) { float* inBuffer = (float*) This->d_OutputBuffer->mBuffers[l_counter].mData;#if _OSX_AU_DEBUG_ fprintf (stderr, "cb3: enqueuing audio data.\n");#endif int l_res = This->d_buffers[l_counter]->enqueue (inBuffer, ActualOutputFrames); if (l_res == -1) res = -1; } if (res == -1) {// data coming in too fast// drop oldest buffer fputs ("aO", stderr); fflush (stderr);// set the local number of samples available to the max This->d_queueSampleCount = This->d_buffers[0]->buffer_length_items (); } else {// keep up the local sample count This->d_queueSampleCount += ActualOutputFrames; }#if _OSX_AU_DEBUG_ fprintf (stderr, "cb4: #OI = %4ld, #Cnt = %4ld, mSC = %ld, \n", ActualOutputFrames, This->d_queueSampleCount, This->d_max_sample_count);#endif// signal that data is available, if appropraite This->d_cond_data->signal ();#if _OSX_AU_DEBUG_ fprintf (stderr, "cb5: releasing internal mutex.\n");#endif// release control to allow for other processing parts to run This->d_internal->unlock ();#if _OSX_AU_DEBUG_ fprintf (stderr, "cb6: returning.\n");#endif return (err);}voidaudio_osx_source::SetDefaultInputDeviceAsCurrent(){// set the default input device AudioDeviceID deviceID; UInt32 dataSize = sizeof (AudioDeviceID); AudioHardwareGetProperty (kAudioHardwarePropertyDefaultInputDevice, &dataSize, &deviceID); OSStatus err = AudioUnitSetProperty (d_InputAU, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, sizeof (AudioDeviceID)); CheckErrorAndThrow (err, "AudioUnitSetProperty Current Device", "audio_osx_source::SetDefaultInputDeviceAsCurrent");}#if _OSX_DO_LISTENERS_OSStatusaudio_osx_source::HardwareListener(AudioHardwarePropertyID inPropertyID, void *inClientData){ OSStatus err = noErr; audio_osx_source* This = static_cast<audio_osx_source*>(inClientData); fprintf (stderr, "a_o_s::HardwareListener\n");// set the new default hardware input device for use by our AU This->SetDefaultInputDeviceAsCurrent ();// reset the converter to tell it that the stream has changed err = AudioConverterReset (This->d_AudioConverter); CheckErrorAndThrow (err, "AudioConverterReset", "audio_osx_source::UnitListener"); return (err);}OSStatusaudio_osx_source::UnitListener(void *inRefCon, AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement){ OSStatus err = noErr; audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon); AudioStreamBasicDescription asbd; fprintf (stderr, "a_o_s::UnitListener\n");// get the converter's input ASBD (for printing) UInt32 propertySize = sizeof (asbd); err = AudioConverterGetProperty (This->d_AudioConverter, kAudioConverterCurrentInputStreamDescription, &propertySize, &asbd); CheckErrorAndThrow (err, "AudioConverterGetProperty " "CurrentInputStreamDescription", "audio_osx_source::UnitListener"); fprintf (stderr, "UnitListener: Input Source changed.\n" "Old Source Output Info:\n"); PrintStreamDesc (&asbd);// get the new input unit's output ASBD propertySize = sizeof (asbd); err = AudioUnitGetProperty (This->d_InputAU, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &asbd, &propertySize); CheckErrorAndThrow (err, "AudioUnitGetProperty StreamFormat", "audio_osx_source::UnitListener"); fprintf (stderr, "New Source Output Info:\n"); PrintStreamDesc (&asbd);// set the converter's input ASBD to this err = AudioConverterSetProperty (This->d_AudioConverter, kAudioConverterCurrentInputStreamDescription, propertySize, &asbd); CheckErrorAndThrow (err, "AudioConverterSetProperty " "CurrentInputStreamDescription", "audio_osx_source::UnitListener");// reset the converter to tell it that the stream has changed err = AudioConverterReset (This->d_AudioConverter); CheckErrorAndThrow (err, "AudioConverterReset", "audio_osx_source::UnitListener"); return (err);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -