//_____________________________________________________________________________ // inFramesToAllocate == 0 implies the AudioUnit's max-frames-per-slice will be used void AUIOElement::AllocateBuffer(UInt32 inFramesToAllocate) { if (GetAudioUnit()->HasBegunInitializing()) { UInt32 framesToAllocate = inFramesToAllocate > 0 ? inFramesToAllocate : GetAudioUnit()->GetMaxFramesPerSlice(); // printf ("will allocate: %d\n", (int)((mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0)); mIOBuffer.Allocate(mStreamFormat, (mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0); } }
void ResonatorNote::Attack(const MusicDeviceNoteParams &inParams) { ResonatorInstrumentBase* synth = (ResonatorInstrumentBase*) GetAudioUnit(); synth->res = (int)synth->Globals()->GetParameter(kResonatorParam_Resolution); synth->mat = (int)synth->Globals()->GetParameter(kResonatorParam_Material); synth->noteHit = (abs((int) inParams.mPitch - LOW_KEY))%synth->numThump; #ifdef DEBUG_PRINT printf("pitch: %d noteHit: %ld\n,",(int) inParams.mPitch,synth->noteHit); printf("computing with res: %ld using material: %ld\n",synth->res,synth->mat); #endif resonator->SetEigenData(synth->eigendata[synth->res*synth->numRes + synth->mat]); // cbnote all of the inaudible ones removed resonator->SetSampleRate(SampleRate()); resonator->SetRenderParameters( (int) synth->Globals()->GetParameter (kResonatorParam_NumberModes), synth->Globals()->GetParameter(kResonatorParam_DeltaFreqScale), synth->Globals()->GetParameter (kResonatorParam_DeltaAlpha1), synth->Globals()->GetParameter (kResonatorParam_DeltaAlpha2), synth->Globals()->GetParameter(kResonatorParam_DeltaSoundScale) ); resonator->Thump(inParams.mVelocity/128.0, synth->thumpers[synth->noteHit], synth->Globals()->GetParameter (kResonatorParam_ThumpBase)); // resonator only needs to know where SendNoteNotification (kAudioUnitEvent_BeginParameterChangeGesture, kParam_NoteOnEvent); }
OSStatus SynthGroupElement::Render(SInt64 inAbsoluteSampleFrame, UInt32 inNumberFrames, AUScope &outputs) { // Avoid duplicate calls at same sample offset if (inAbsoluteSampleFrame != mCurrentAbsoluteFrame) { mCurrentAbsoluteFrame = inAbsoluteSampleFrame; AudioBufferList* buffArray[16]; UInt32 numOutputs = outputs.GetNumberOfElements(); for (UInt32 outBus = 0; outBus < numOutputs && outBus < 16; ++outBus) { buffArray[outBus] = &GetAudioUnit()->GetOutput(outBus)->GetBufferList(); } for (UInt32 i=0 ; i<kNumberOfSoundingNoteStates; ++i) { SynthNote *note = mNoteList[i].mHead; while (note) { #if DEBUG_PRINT_RENDER printf("SynthGroupElement::Render: state %d, note %p\n", i, note); #endif SynthNote *nextNote = note->mNext; OSStatus err = note->Render(inAbsoluteSampleFrame, inNumberFrames, buffArray, numOutputs); if (err) return err; note = nextNote; } } } return noErr; }
void ResonatorNote::SendNoteNotification (AudioUnitEventType inEventType, UInt32 inParamID) { AudioUnitEvent event; event.mEventType = inEventType; event.mArgument.mParameter.mAudioUnit = GetAudioUnit()->GetComponentInstance(); event.mArgument.mParameter.mParameterID = inParamID; event.mArgument.mParameter.mScope = kAudioUnitScope_Global; event.mArgument.mParameter.mElement = 0; AUEventListenerNotify(NULL, NULL, &event); }
OSStatus SynthGroupElement::Render(UInt32 inNumberFrames) { SynthNote *note; AudioBufferList& bufferList = GetAudioUnit()->GetOutput(mOutputBus)->GetBufferList(); for (UInt32 i=0 ; i<kNumberOfSoundingNoteStates; ++i) { note = mNoteList[i].mHead; while (note) { #if DEBUG_PRINT printf(" note %d %08X %d\n", i, note, inNumberFrames); #endif SynthNote *nextNote = note->mNext; OSStatus err = note->Render(inNumberFrames, bufferList); if (err) return err; note = nextNote; } } return noErr; }
bool HSNote::Attack(const MusicDeviceNoteParams &inParams) { HSPad* hsp = (HSPad*) GetAudioUnit(); wavetable = hsp->getWavetable(); float freq = Frequency()*(1-GetGlobalParameter(kParameter_TouchSensitivity)*pow(inParams.mVelocity/127., 2.)); wavetable_idx = wavetable->closestMatchingWavetable(freq); wavetable_num_samples = wavetable->getNumSamples(); wavetable_sample_rate = wavetable->getSampleRate(); double sampleRate = SampleRate(); phase = (rand()/(RAND_MAX+1.0))*wavetable_num_samples; amp = 0.; maxamp = 0.4 * pow(inParams.mVelocity/127., 2.); float at = GetGlobalParameter(kParameter_AttackTime); // If at is 0, we set up_slope to maxamp/50. That is big enough to start the note // seemingly immediately, yet avoiding an ugly chipping sound that comes if you set // it to maxamp. up_slope = maxamp / (at==0.0?50.0:(at/1000.0 * sampleRate)); float rt = GetGlobalParameter(kParameter_ReleaseTime); if (rt == 0) { // This is not 0, because that makes an ugly chipping sound when the note // is released. 0.99 is small enough to stop the note seemingly immediately dn_slope = 0.99; } else { double num_frames = rt/1000.0 * sampleRate; double off_threshold = 0.01; // 20dB dn_slope = pow(off_threshold, (double)1.0/num_frames); } fast_dn_slope = -maxamp / (0.005 * sampleRate); return true; }
double SynthNote::SampleRate() { return GetAudioUnit()->GetOutput(0)->GetStreamFormat().mSampleRate; }