// Could we get iph-based instruments support sample-exact models by using a // frame-length of 1 while rendering? void sf2Instrument::play( sampleFrame * _working_buffer ) { const fpp_t frames = engine::mixer()->framesPerPeriod(); m_synthMutex.lock(); const int currentMidiPitch = instrumentTrack()->midiPitch(); if( m_lastMidiPitch != currentMidiPitch ) { m_lastMidiPitch = currentMidiPitch; fluid_synth_pitch_bend( m_synth, m_channel, m_lastMidiPitch ); } const int currentMidiPitchRange = instrumentTrack()->midiPitchRange(); if( m_lastMidiPitchRange != currentMidiPitchRange ) { m_lastMidiPitchRange = currentMidiPitchRange; fluid_synth_pitch_wheel_sens( m_synth, m_channel, m_lastMidiPitchRange ); } if( m_internalSampleRate < engine::mixer()->processingSampleRate() && m_srcState != NULL ) { const fpp_t f = frames * m_internalSampleRate / engine::mixer()->processingSampleRate(); #ifdef __GNUC__ sampleFrame tmp[f]; #else sampleFrame * tmp = new sampleFrame[f]; #endif fluid_synth_write_float( m_synth, f, tmp, 0, 2, tmp, 1, 2 ); SRC_DATA src_data; src_data.data_in = tmp[0]; src_data.data_out = _working_buffer[0]; src_data.input_frames = f; src_data.output_frames = frames; src_data.src_ratio = (double) frames / f; src_data.end_of_input = 0; int error = src_process( m_srcState, &src_data ); #ifndef __GNUC__ delete[] tmp; #endif if( error ) { qCritical( "sf2Instrument: error while resampling: %s", src_strerror( error ) ); } if( src_data.output_frames_gen > frames ) { qCritical( "sf2Instrument: not enough frames: %ld / %d", src_data.output_frames_gen, frames ); } } else { fluid_synth_write_float( m_synth, frames, _working_buffer, 0, 2, _working_buffer, 1, 2 ); } m_synthMutex.unlock(); instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL ); }
/* PortAudio callback * fluid_portaudio_run */ static int fluid_portaudio_run (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { fluid_portaudio_driver_t *dev = (fluid_portaudio_driver_t *)userData; if (dev->callback) { float* left = dev->buffers[0]; float* right = dev->buffers[1]; int i, r, l; long len = frameCount; float* buffer = (float *)output; // callback fills dev->buffers (*dev->callback)(dev->data, len, 0, NULL, 2, dev->buffers); bzero(buffer, dev->chansOpen*len*sizeof(float)); for (i = 0, l = dev->chanL, r = dev->chanR; i < len; i++, l += dev->chansOpen, r += dev->chansOpen) { buffer[l] = left[i]; buffer[r] = right[i]; } } else /* it's as simple as that: */ fluid_synth_write_float ((fluid_synth_t *)dev->data, frameCount, output, dev->chanL, dev->chansOpen, output, dev->chanR, dev->chansOpen); return 0; }
OSStatus fluid_core_audio_callback ( void *data, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { int i, k; fluid_core_audio_driver_t* dev = (fluid_core_audio_driver_t*) data; int len = inNumberFrames; float* buffer = ioData->mBuffers[0].mData; if (dev->callback) { float* left = dev->buffers[0]; float* right = dev->buffers[1]; (*dev->callback)(dev->data, len, 0, NULL, 2, dev->buffers); for (i = 0, k = 0; i < len; i++) { buffer[k++] = left[i]; buffer[k++] = right[i]; } } else fluid_synth_write_float((fluid_synth_t*) dev->data, len, buffer, 0, 2, buffer, 1, 2); return noErr; }
int audio(CSOUND *csound) { #pragma omp critical (critical_section_fluid_all_out) { uint32_t offset = opds.insdshead->ksmps_offset; uint32_t early = opds.insdshead->ksmps_no_end; if (UNLIKELY(offset)) { memset(aLeftOut, '\0', offset*sizeof(MYFLT)); memset(aRightOut, '\0', offset*sizeof(MYFLT)); } if (UNLIKELY(early)) { ksmps -= early; memset(&aLeftOut[ksmps], '\0', early*sizeof(MYFLT)); memset(&aRightOut[ksmps], '\0', early*sizeof(MYFLT)); } std::vector<fluid_synth_t *> &fluidSynths = getFluidSynthsForCsoundInstances()[csound]; for (frame = offset; frame < ksmps; frame++) { aLeftOut[frame] = FL(0.0); aRightOut[frame] = FL(0.0); for (size_t i = 0, n = fluidSynths.size(); i < n; i++) { fluid_synth_t *fluidSynth = fluidSynths[i]; leftSample = FL(0.0); rightSample = FL(0.0); fluid_synth_write_float(fluidSynth, 1, &leftSample, 0, 1, &rightSample, 0, 1); aLeftOut[frame] += (MYFLT) leftSample /* * csound->e0dbfs */; aRightOut[frame] += (MYFLT) rightSample /* * csound->e0dbfs */; } } } return OK; }
int audio(CSOUND *csound) { #pragma omp critical (critical_section_fluid_out) { uint32_t offset = opds.insdshead->ksmps_offset; uint32_t early = opds.insdshead->ksmps_no_end; if (UNLIKELY(offset)) { memset(aLeftOut, '\0', offset*sizeof(MYFLT)); memset(aRightOut, '\0', offset*sizeof(MYFLT)); } if (UNLIKELY(early)) { ksmps -= early; memset(&aLeftOut[ksmps], '\0', early*sizeof(MYFLT)); memset(&aRightOut[ksmps], '\0', early*sizeof(MYFLT)); } for (frame = offset; frame < ksmps; frame++) { leftSample = 0.0f; rightSample = 0.0f; fluid_synth_write_float(fluidSynth, 1, &leftSample, 0, 1, &rightSample, 0, 1); aLeftOut[frame] = leftSample /* * csound->e0dbfs */; aRightOut[frame] = rightSample /* * csound->e0dbfs */; } } return OK; }
static void RT_process(SoundPlugin *plugin, int64_t time, int num_frames, float **inputs, float **outputs){ Data *data = (Data*)plugin->data; //data =NULL; // crashreporter test. //printf("telling sequencer that it is time %d\n",(int)data->time); fluid_sequencer_process(data->sequencer, get_fluidsynth_time(data,data->time)); data->time += num_frames; // What's the difference between fluid_synth_write_float and fluid_synth_nwrite_float? Sounds to me like they produce exactly the same sound. #if 0 if(fluid_synth_write_float(data->synth,num_frames,outputs[0],0,1,outputs[1],0,1)==FLUID_FAILED) printf("fluid_synth_write_float failed\n"); #else if(fluid_synth_nwrite_float(data->synth,num_frames, &outputs[0], &outputs[1], NULL, NULL)==FLUID_FAILED) printf("fluid_synth_write_float failed\n"); #endif if(data->new_data != NULL){ RT_fade_out(outputs[0],num_frames); RT_fade_out(outputs[1],num_frames); plugin->data = data->new_data; // hmm. data->new_data = NULL; RSEMAPHORE_signal(data->signal_from_RT,1); } }
t_int *soundfonts_perform(t_int *input) { t_soundfonts *instance = (t_soundfonts *)(input[1]); t_sample *outL = (t_sample *)(input[2]); t_sample *outR = (t_sample *)(input[3]); int n = (int)(input[4]); fluid_synth_write_float(instance->synth, n, outL, 0, 1, outR, 0, 1); return input + 5; }
void sf2Instrument::renderFrames( f_cnt_t frames, sampleFrame * buf ) { m_synthMutex.lock(); if( m_internalSampleRate < Engine::mixer()->processingSampleRate() && m_srcState != NULL ) { const fpp_t f = frames * m_internalSampleRate / Engine::mixer()->processingSampleRate(); #ifdef __GNUC__ sampleFrame tmp[f]; #else sampleFrame * tmp = new sampleFrame[f]; #endif fluid_synth_write_float( m_synth, f, tmp, 0, 2, tmp, 1, 2 ); SRC_DATA src_data; src_data.data_in = (float *)tmp; src_data.data_out = (float *)buf; src_data.input_frames = f; src_data.output_frames = frames; src_data.src_ratio = (double) frames / f; src_data.end_of_input = 0; int error = src_process( m_srcState, &src_data ); #ifndef __GNUC__ delete[] tmp; #endif if( error ) { qCritical( "sf2Instrument: error while resampling: %s", src_strerror( error ) ); } if( src_data.output_frames_gen > frames ) { qCritical( "sf2Instrument: not enough frames: %ld / %d", src_data.output_frames_gen, frames ); } } else { fluid_synth_write_float( m_synth, frames, buf, 0, 2, buf, 1, 2 ); } m_synthMutex.unlock(); }
void ISynth::process(unsigned /*pos*/, float** ports, int offset, int n) { if (!_busy) { /* // // get and process all pending events from the // synthesizer GUI // while (gui->fifoSize()) processEvent(gui->readEvent()); */ fluid_synth_write_float(_fluidsynth, n, ports[0], offset, 1, ports[1], offset, 1); } // printf("%f %f\n", *ports[0], *(ports[0]+1)); }
static GstFlowReturn produce_samples (GstFluidDec * fluiddec, GstClockTime pts, guint64 sample) { GstClockTime duration, timestamp; guint64 samples, offset; GstMapInfo info; GstBuffer *outbuf; samples = sample - fluiddec->last_sample; duration = pts - fluiddec->last_pts; offset = fluiddec->last_sample; timestamp = fluiddec->last_pts; fluiddec->last_pts = pts; fluiddec->last_sample = sample; if (samples == 0) return GST_FLOW_OK; GST_DEBUG_OBJECT (fluiddec, "duration %" GST_TIME_FORMAT ", samples %" G_GUINT64_FORMAT, GST_TIME_ARGS (duration), samples); outbuf = gst_buffer_new_allocate (NULL, samples * FLUID_DEC_BPS, NULL); gst_buffer_map (outbuf, &info, GST_MAP_WRITE); fluid_synth_write_float (fluiddec->synth, samples, info.data, 0, 2, info.data, 1, 2); gst_buffer_unmap (outbuf, &info); GST_BUFFER_DTS (outbuf) = timestamp; GST_BUFFER_PTS (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = duration; GST_BUFFER_OFFSET (outbuf) = offset; GST_BUFFER_OFFSET_END (outbuf) = offset + samples; if (fluiddec->discont) { GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); fluiddec->discont = FALSE; } return gst_pad_push (fluiddec->srcpad, outbuf); }
static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block) { block_t *p_block; decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_out = NULL; if (pp_block == NULL) return NULL; p_block = *pp_block; if (p_block == NULL) return NULL; *pp_block = NULL; if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date)) date_Set (&p_sys->end_date, p_block->i_pts); else if (p_block->i_pts < date_Get (&p_sys->end_date)) { msg_Warn (p_dec, "MIDI message in the past?"); goto drop; } if (p_block->i_buffer < 1) goto drop; uint8_t event = p_block->p_buffer[0]; uint8_t channel = p_block->p_buffer[0] & 0xf; event &= 0xF0; if (event == 0xF0) switch (channel) { case 0: if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7) { case 7: msg_Warn (p_dec, "fragmented SysEx not implemented"); goto drop; } fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1, p_block->i_buffer - 2, NULL, NULL, NULL, 0); break; case 0xF: fluid_synth_system_reset (p_sys->synth); break; } uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0; uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0; switch (event & 0xF0) { case 0x80: fluid_synth_noteoff (p_sys->synth, channel, p1); break; case 0x90: fluid_synth_noteon (p_sys->synth, channel, p1, p2); break; /*case 0xA0: note aftertouch not implemented */ case 0xB0: fluid_synth_cc (p_sys->synth, channel, p1, p2); break; case 0xC0: fluid_synth_program_change (p_sys->synth, channel, p1); break; case 0xD0: fluid_synth_channel_pressure (p_sys->synth, channel, p1); break; case 0xE0: fluid_synth_pitch_bend (p_sys->synth, channel, (p2 << 7) | p1); break; } unsigned samples = (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000; if (samples == 0) goto drop; p_out = decoder_NewAudioBuffer (p_dec, samples); if (p_out == NULL) goto drop; p_out->i_pts = date_Get (&p_sys->end_date ); p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; fluid_synth_write_float (p_sys->synth, samples, p_out->p_buffer, 0, 2, p_out->p_buffer, 1, 2); drop: block_Release (p_block); return p_out; }
static aout_buffer_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block) { block_t *p_block; decoder_sys_t *p_sys = p_dec->p_sys; aout_buffer_t *p_out = NULL; if (pp_block == NULL) return NULL; p_block = *pp_block; if (p_block == NULL) return NULL; *pp_block = NULL; if (p_block->i_pts && !date_Get (&p_sys->end_date)) date_Set (&p_sys->end_date, p_block->i_pts); else if (p_block->i_pts < date_Get (&p_sys->end_date)) { msg_Warn (p_dec, "MIDI message in the past?"); goto drop; } if (p_block->i_buffer < 1) goto drop; uint8_t channel = p_block->p_buffer[0] & 0xf; uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0; uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0; switch (p_block->p_buffer[0] & 0xf0) { case 0x80: fluid_synth_noteoff (p_sys->synth, channel, p1); break; case 0x90: fluid_synth_noteon (p_sys->synth, channel, p1, p2); break; case 0xB0: fluid_synth_cc (p_sys->synth, channel, p1, p2); break; case 0xC0: fluid_synth_program_change (p_sys->synth, channel, p1); break; case 0xE0: fluid_synth_pitch_bend (p_sys->synth, channel, (p1 << 7) | p2); break; } unsigned samples = (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000; if (samples == 0) return NULL; p_out = decoder_NewAudioBuffer (p_dec, samples); if (p_out == NULL) goto drop; p_out->i_pts = date_Get (&p_sys->end_date ); p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts; if (!p_sys->fixed) fluid_synth_write_float (p_sys->synth, samples, p_out->p_buffer, 0, 2, p_out->p_buffer, 1, 2); else fluid_synth_write_s16 (p_sys->synth, samples, (int16_t *)p_out->p_buffer, 0, 2, (int16_t *)p_out->p_buffer, 1, 2); drop: block_Release (p_block); return p_out; }
void WriteSamples(ALuint count, float *buffer) { fluid_synth_write_float(fluidSynth, count, buffer, 0, 2, buffer, 1, 2); }
// for Chugins extending UGen void tick( SAMPLE *in, SAMPLE *out ) { // default: this passes whatever input is patched into Chugin fluid_synth_write_float(m_synth, 1, out, 0, 0, out+1, 0, 0); }
void fluidsynth_render_audio (unsigned int nframes, float *left_channel, float *right_channel) { //printf("\nsynth == %d, nframes == %d, left_channel == %f right_channel == %f\n",synth, nframes, left_channel, right_channel); fluid_synth_write_float (synth, nframes, left_channel, 0, 1, right_channel, 0, 1); }