bool AREngine::initHardware(IOService* inProvider) { bool theAnswer = false; if(IOAudioEngine::initHardware(inProvider)) { IOAudioSampleRate theInitialSampleRate = { 0, 0 }; UInt32 theNumberChannels = 0; // create the streams if(CreateStreams(&theInitialSampleRate, &theNumberChannels) && (theInitialSampleRate.whole != 0)) { CreateControls(theNumberChannels); // figure out how long each block is in microseconds mBlockTimeoutMicroseconds = 1000000 * mBlockSize / theInitialSampleRate.whole; setSampleRate(&theInitialSampleRate); // Set the number of sample frames in each buffer setNumSampleFramesPerBuffer(mBlockSize * mNumberBlocks); // set up the timer IOWorkLoop* theWorkLoop = getWorkLoop(); if(theWorkLoop != NULL) { mTimerEventSource = IOTimerEventSource::timerEventSource(this, TimerFired); if(mTimerEventSource != NULL) { theWorkLoop->addEventSource(mTimerEventSource); theAnswer = true; } } // set the safety offset // note that due to cache issues, it probably isn't wise to leave the safety offset at 0, // we set it to 4 here, just to be safe. setSampleOffset(4); // set up the time stamp generator mTimeStampGenerator.SetSampleRate(theInitialSampleRate.whole); mTimeStampGenerator.SetFramesPerRingBuffer(mBlockSize * mNumberBlocks); // nate that the rate scalar is a 4.28 fixed point number // this means that each incremnt is 1/2^28 mTimeStampGenerator.SetRateScalar(1UL << 28); // set the maximum jitter // AbsoluteTime theMaximumJitter = { 0, 0 }; // nanoseconds_to_absolutetime(5ULL * 1000ULL, &theMaximumJitter); // mTimeStampGenerator.SetMaximumJitter(theMaximumJitter.lo); } } return theAnswer; }
bool eqMac2DriverEngine::initHardware(IOService *provider) { bool result = false; IOAudioSampleRate initialSampleRate; IOWorkLoop *wl; //IOLog("eqMac2DriverEngine[%p]::initHardware(%p)\n", this, provider); duringHardwareInit = TRUE; if (!super::initHardware(provider)) { goto Done; } initialSampleRate.whole = 0; initialSampleRate.fraction = 0; if (!createAudioStreams(&initialSampleRate)) { IOLog("eqMac2DriverEngine::initHardware() failed\n"); goto Done; } if (initialSampleRate.whole == 0) { goto Done; } // calculate our timeout in nanosecs, taking care to keep 64bits blockTimeoutNS = blockSize; blockTimeoutNS *= 1000000000; blockTimeoutNS /= initialSampleRate.whole; setSampleRate(&initialSampleRate); // Set the number of sample frames in each buffer setNumSampleFramesPerBuffer(blockSize * numBlocks); wl = getWorkLoop(); if (!wl) { goto Done; } timerEventSource = IOTimerEventSource::timerEventSource(this, ourTimerFired); if (!timerEventSource) { goto Done; } workLoop->addEventSource(timerEventSource); result = true; Done: duringHardwareInit = FALSE; return result; }
bool PhantomAudioEngine::initHardware(IOService *provider) { bool result = false; IOAudioSampleRate initialSampleRate; IOWorkLoop *wl; IOLog("PhantomAudioEngine[%p]::initHardware(%p)\n", this, provider); duringHardwareInit = TRUE; if (!super::initHardware(provider)) { goto Done; } initialSampleRate.whole = 0; initialSampleRate.fraction = 0; if (!createAudioStreams(&initialSampleRate)) { goto Done; } if (initialSampleRate.whole == 0) { goto Done; } blockTimeoutUS = 1000000 * blockSize / initialSampleRate.whole; setSampleRate(&initialSampleRate); // Set the number of sample frames in each buffer setNumSampleFramesPerBuffer(blockSize * numBlocks); wl = getWorkLoop(); if (!wl) { goto Done; } timerEventSource = IOTimerEventSource::timerEventSource(this, timerFired); if (!timerEventSource) { goto Done; } workLoop->addEventSource(timerEventSource); result = true; Done: duringHardwareInit = FALSE; return result; }
void kXAudioEngine::free_all() { debug("kXAudioEngine[%p]::free_all() - %s\n",this,is_running?"[still running!]":""); if(is_running) stopAudioEngine(); // free buffers setNumSampleFramesPerBuffer(0); for(int i=0;i<n_channels;i++) { if(out_streams[i]) { out_streams[i]->setSampleBuffer (NULL, 0); out_streams[i]->release(); out_streams[i]=NULL; } if(in_streams[i]) { in_streams[i]->setSampleBuffer (NULL, 0); in_streams[i]->release(); in_streams[i]=NULL; } if(hw) { freeAudioStream(i,kIOAudioStreamDirectionInput); freeAudioStream(i,kIOAudioStreamDirectionOutput); } } if(hw) { if((hw->initialized&KX_ENGINE_INITED) && !(hw->initialized&KX_DEVICE_INITED)) { debug("kXAudioEngine[%p]::free_all() - close iKX interface\n",this); kx_close(&hw); hw=0; } else { debug("kXAudioEngine[%p]::free_all() - dereference iKX interface\n",this); hw->initialized&=(~KX_ENGINE_INITED); hw=NULL; } } else debug("kXAudioEngine[%p]::free_all() - iKX interface already closed\n",this); }
bool PAEngine::initHardware(IOService *provider) { UInt32 sampleRates[] = SAMPLERATES; IOAudioSampleRate sampleRate; debugFunctionEnter(); device = OSDynamicCast(PADevice, provider); if (!device) return false; if (!super::initHardware(provider)) return false; virtualDeviceArray = OSArray::withCapacity(1); if (!virtualDeviceArray) { IOLog("%s(%p)::%s unable to allocate memory\n", getName(), this, __func__); return false; } sampleRate.whole = sampleRates[0]; sampleRate.fraction = 0; setSampleRate(&sampleRate); setNewSampleRate(sampleRate.whole); setDescription(info->name); setNumSampleFramesPerBuffer(NUM_SAMPLE_FRAMES); info->audioBufferSize = AUDIO_BUFFER_SIZE * nStreams; audioInBuf = IOBufferMemoryDescriptor::withCapacity(info->audioBufferSize, kIODirectionInOut); audioOutBuf = IOBufferMemoryDescriptor::withCapacity(info->audioBufferSize, kIODirectionInOut); if (!audioInBuf || !audioOutBuf) { IOLog("%s(%p)::%s unable to allocate memory\n", getName(), this, __func__); return false; } audioInBuf->prepare(); audioOutBuf->prepare(); for (UInt32 i = 0; i < nStreams; i++) { IOAudioStream *stream; char *streamBuf; if (i * CHANNELS_PER_STREAM < channelsIn) { streamBuf = (char *) audioInBuf->getBytesNoCopy() + (i * AUDIO_BUFFER_SIZE); stream = createNewAudioStream(kIOAudioStreamDirectionInput, streamBuf); if (!stream) { IOLog("%s(%p)::%s failed to create audio streams\n", getName(), this, __func__); return false; } addAudioStream(stream); audioStream[i * 2] = stream; stream->release(); } if (i * CHANNELS_PER_STREAM < channelsOut) { streamBuf = (char *) audioOutBuf->getBytesNoCopy() + (i * AUDIO_BUFFER_SIZE); stream = createNewAudioStream(kIOAudioStreamDirectionOutput, streamBuf); if (!stream) { IOLog("%s(%p)::%s failed to create audio streams\n", getName(), this, __func__); return false; } addAudioStream(stream); audioStream[(i * 2) + 1] = stream; stream->release(); } } if (info->audioContentType == kPADeviceAudioContentMixdown) return addVirtualDevice(info, audioInBuf, audioOutBuf, this) == kIOReturnSuccess; return true; }
bool kXAudioEngine::initHardware(IOService *provider) { bool result = false; IOAudioSampleRate initialSampleRate; IOAudioStream *audioStream; debug("kXAudioEngine[%p]::initHardware(%p)\n", this, provider); if (!super::initHardware(provider)) { goto Done; } // Setup the initial sample rate for the audio engine initialSampleRate.whole = sampling_rate; initialSampleRate.fraction = 0; char device_name[KX_MAX_STRING]; strncpy(device_name,"kX ",KX_MAX_STRING); strncat(device_name,hw->card_name,KX_MAX_STRING); setDescription(device_name); setSampleRate(&initialSampleRate); setClockDomain(); // =kIOAudioNewClockDomain // calculate kx_sample_offset if(hw->is_10k2) { // setSampleOffset(28); // 28 samples setSampleLatency(28+1); } else { // setSampleOffset(32); // 32 samples setSampleLatency(32+1); } // Allocate our input and output buffers for(int i=0;i<n_channels;i++) { // Create an IOAudioStream for each buffer and add it to this audio engine audioStream = createNewAudioStream(i,kIOAudioStreamDirectionOutput, 1*n_frames*bps/8); if (!audioStream) { goto Done; } addAudioStream(audioStream); out_streams[i]=audioStream; } // recording audioStream = createNewAudioStream(0,kIOAudioStreamDirectionInput, n_channels*n_frames*bps/8); if (!audioStream) { goto Done; } addAudioStream(audioStream); in_streams[0]=audioStream; dump_addr(); // Set the number of sample frames in each buffer setNumSampleFramesPerBuffer(n_frames); result = true; Done: if(result==false) free_all(); return result; }