void SampleBuffer::loadFromBase64( const QString & _data ) { char * dst = NULL; int dsize = 0; base64::decode( _data, &dst, &dsize ); #ifdef LMMS_HAVE_FLAC_STREAM_DECODER_H QByteArray orig_data = QByteArray::fromRawData( dst, dsize ); QBuffer ba_reader( &orig_data ); ba_reader.open( QBuffer::ReadOnly ); QBuffer ba_writer; ba_writer.open( QBuffer::WriteOnly ); flacStreamDecoderClientData cdata = { &ba_reader, &ba_writer } ; FLAC__StreamDecoder * flac_dec = FLAC__stream_decoder_new(); FLAC__stream_decoder_set_read_callback( flac_dec, flacStreamDecoderReadCallback ); FLAC__stream_decoder_set_write_callback( flac_dec, flacStreamDecoderWriteCallback ); FLAC__stream_decoder_set_error_callback( flac_dec, flacStreamDecoderErrorCallback ); FLAC__stream_decoder_set_metadata_callback( flac_dec, flacStreamDecoderMetadataCallback ); FLAC__stream_decoder_set_client_data( flac_dec, &cdata ); FLAC__stream_decoder_init( flac_dec ); FLAC__stream_decoder_process_until_end_of_stream( flac_dec ); FLAC__stream_decoder_finish( flac_dec ); FLAC__stream_decoder_delete( flac_dec ); ba_reader.close(); orig_data = ba_writer.buffer(); printf("%d\n", (int) orig_data.size() ); m_origFrames = orig_data.size() / sizeof( sampleFrame ); MM_FREE( m_origData ); m_origData = MM_ALLOC( sampleFrame, m_origFrames ); memcpy( m_origData, orig_data.data(), orig_data.size() ); #else /* LMMS_HAVE_FLAC_STREAM_DECODER_H */ m_origFrames = dsize / sizeof( sampleFrame ); MM_FREE( m_origData ); m_origData = MM_ALLOC( sampleFrame, m_origFrames ); memcpy( m_origData, dst, dsize ); #endif delete[] dst; m_audioFile = QString(); update(); }
CrossoverEQEffect::CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ) : Effect( &crossovereq_plugin_descriptor, parent, key ), m_controls( this ), m_sampleRate( Engine::mixer()->processingSampleRate() ), m_lp1( m_sampleRate ), m_lp2( m_sampleRate ), m_lp3( m_sampleRate ), m_hp2( m_sampleRate ), m_hp3( m_sampleRate ), m_hp4( m_sampleRate ), m_needsUpdate( true ) { m_tmp1 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() ); m_tmp2 = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() ); m_work = MM_ALLOC( sampleFrame, Engine::mixer()->framesPerPeriod() ); }
void SampleBuffer::directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _channels) { m_data = MM_ALLOC( sampleFrame, _frames ); const int ch = ( _channels > 1 ) ? 1 : 0; // if reversing is on, we also reverse when // scaling if( m_reversed ) { int idx = ( _frames - 1 ) * _channels; for( f_cnt_t frame = 0; frame < _frames; ++frame ) { m_data[frame][0] = _fbuf[idx+0]; m_data[frame][1] = _fbuf[idx+ch]; idx -= _channels; } } else { int idx = 0; for( f_cnt_t frame = 0; frame < _frames; ++frame ) { m_data[frame][0] = _fbuf[idx+0]; m_data[frame][1] = _fbuf[idx+ch]; idx += _channels; } } delete[] _fbuf; }
void SampleBuffer::convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels) { // following code transforms int-samples into // float-samples and does amplifying & reversing const float fac = 1 / OUTPUT_SAMPLE_MULTIPLIER; m_data = MM_ALLOC( sampleFrame, _frames ); const int ch = ( _channels > 1 ) ? 1 : 0; // if reversing is on, we also reverse when // scaling if( m_reversed ) { int idx = ( _frames - 1 ) * _channels; for( f_cnt_t frame = 0; frame < _frames; ++frame ) { m_data[frame][0] = _ibuf[idx+0] * fac; m_data[frame][1] = _ibuf[idx+ch] * fac; idx -= _channels; } } else { int idx = 0; for( f_cnt_t frame = 0; frame < _frames; ++frame ) { m_data[frame][0] = _ibuf[idx+0] * fac; m_data[frame][1] = _ibuf[idx+ch] * fac; idx += _channels; } } delete[] _ibuf; }
static struct timer_node * timer_add(struct timer *T, uint32_t ud,const void * cb,int sz,int time) { struct timer_node *node = (struct timer_node *)MM_ALLOC(sizeof(*node)+ sizeof(timer_event) + sz); timer_event * ev = (timer_event*)(node+1); ev->ud = ud; ev->sz = sz; ev->period = (time < 0)?-time:0; time = (time < 0 )? -time : time; memcpy(ev->data, cb, sz); ev->data[sz] = 0;//dump ez LOCK(T); node->expire=time+T->time; add_node(T,node); UNLOCK(T); return node; }
static struct timer * timer_create_timer() { struct timer *r=(struct timer *)MM_ALLOC(sizeof(struct timer)); memset(r,0,sizeof(*r)); int i,j; for (i=0;i<TIME_NEAR;i++) { link_clear(&r->near[i]); } for (i=0;i<4;i++) { for (j=0;j<TIME_LEVEL;j++) { link_clear(&r->t[i][j]); } } r->lock = 0; r->current = 0; return r; }
void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, bool _keep_settings ) { // do samplerate-conversion to our default-samplerate if( _src_sr != engine::mixer()->baseSampleRate() ) { SampleBuffer * resampled = resample( this, _src_sr, engine::mixer()->baseSampleRate() ); MM_FREE( m_data ); m_frames = resampled->frames(); m_data = MM_ALLOC( sampleFrame, m_frames ); memcpy( m_data, resampled->data(), m_frames * sizeof( sampleFrame ) ); delete resampled; } if( _keep_settings == false ) { // update frame-variables m_loopStartFrame = m_startFrame = 0; m_loopEndFrame = m_endFrame = m_frames; } }
SampleBuffer::SampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) : m_audioFile( "" ), m_origData( NULL ), m_origFrames( 0 ), m_data( NULL ), m_frames( 0 ), m_startFrame( 0 ), m_endFrame( 0 ), m_loopStartFrame( 0 ), m_loopEndFrame( 0 ), m_amplification( 1.0f ), m_reversed( false ), m_frequency( BaseFreq ), m_sampleRate( engine::mixer()->baseSampleRate() ) { if( _frames > 0 ) { m_origData = MM_ALLOC( sampleFrame, _frames ); memcpy( m_origData, _data, _frames * BYTES_PER_FRAME ); m_origFrames = _frames; } connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( sampleRateChanged() ) ); update(); }
sampleFrame ** BufferManager::s_available; QAtomicInt BufferManager::s_availableIndex = 0; sampleFrame ** BufferManager::s_released; QAtomicInt BufferManager::s_releasedIndex = 0; //QReadWriteLock BufferManager::s_mutex; int BufferManager::s_size; void BufferManager::init( fpp_t framesPerPeriod ) { s_available = MM_ALLOC( sampleFrame*, BM_INITIAL_BUFFERS ); s_released = MM_ALLOC( sampleFrame*, BM_INITIAL_BUFFERS ); int c = framesPerPeriod * BM_INITIAL_BUFFERS; sampleFrame * b = MM_ALLOC( sampleFrame, c ); for( int i = 0; i < BM_INITIAL_BUFFERS; ++i ) { s_available[ i ] = b; b += framesPerPeriod; } s_availableIndex = BM_INITIAL_BUFFERS - 1; s_size = BM_INITIAL_BUFFERS; } sampleFrame * BufferManager::acquire() { if( s_availableIndex < 0 ) {
sampleFrame * SampleBuffer::getSampleFragment( f_cnt_t _index, f_cnt_t _frames, LoopMode _loopmode, sampleFrame * * _tmp, bool * _backwards, f_cnt_t _loopstart, f_cnt_t _loopend, f_cnt_t _end ) const { if( _loopmode == LoopOff ) { if( _index + _frames <= _end ) { return m_data + _index; } } else if( _loopmode == LoopOn ) { if( _index + _frames <= _loopend ) { return m_data + _index; } } else { if( ! *_backwards && _index + _frames < _loopend ) return m_data + _index; } *_tmp = MM_ALLOC( sampleFrame, _frames ); if( _loopmode == LoopOff ) { f_cnt_t available = _end - _index; memcpy( *_tmp, m_data + _index, available * BYTES_PER_FRAME ); memset( *_tmp + available, 0, ( _frames - available ) * BYTES_PER_FRAME ); } else if( _loopmode == LoopOn ) { f_cnt_t copied = qMin( _frames, _loopend - _index ); memcpy( *_tmp, m_data + _index, copied * BYTES_PER_FRAME ); f_cnt_t loop_frames = _loopend - _loopstart; while( copied < _frames ) { f_cnt_t todo = qMin( _frames - copied, loop_frames ); memcpy( *_tmp + copied, m_data + _loopstart, todo * BYTES_PER_FRAME ); copied += todo; } } else { f_cnt_t pos = _index; bool backwards = pos < _loopstart ? false : *_backwards; f_cnt_t copied = 0; if( backwards ) { copied = qMin( _frames, pos - _loopstart ); for( int i=0; i < copied; i++ ) { (*_tmp)[i][0] = m_data[ pos - i ][0]; (*_tmp)[i][1] = m_data[ pos - i ][1]; } pos -= copied; if( pos == _loopstart ) backwards = false; } else { copied = qMin( _frames, _loopend - pos ); memcpy( *_tmp, m_data + pos, copied * BYTES_PER_FRAME ); pos += copied; if( pos == _loopend ) backwards = true; } while( copied < _frames ) { if( backwards ) { f_cnt_t todo = qMin( _frames - copied, pos - _loopstart ); for ( int i=0; i < todo; i++ ) { (*_tmp)[ copied + i ][0] = m_data[ pos - i ][0]; (*_tmp)[ copied + i ][1] = m_data[ pos - i ][1]; } pos -= todo; copied += todo; if( pos <= _loopstart ) backwards = false; } else { f_cnt_t todo = qMin( _frames - copied, _loopend - pos ); memcpy( *_tmp + copied, m_data + pos, todo * BYTES_PER_FRAME ); pos += todo; copied += todo; if( pos >= _loopend ) backwards = true; } } *_backwards = backwards; } return *_tmp; }
void SampleBuffer::update( bool _keep_settings ) { const bool lock = ( m_data != NULL ); if( lock ) { m_varLock.lockForWrite(); MM_FREE( m_data ); } if( m_audioFile.isEmpty() && m_origData != NULL && m_origFrames > 0 ) { // TODO: reverse- and amplification-property is not covered // by following code... m_data = MM_ALLOC( sampleFrame, m_origFrames ); memcpy( m_data, m_origData, m_origFrames * BYTES_PER_FRAME ); if( _keep_settings == false ) { m_frames = m_origFrames; m_loopStartFrame = m_startFrame = 0; m_loopEndFrame = m_endFrame = m_frames; } } else if( !m_audioFile.isEmpty() ) { QString file = tryToMakeAbsolute( m_audioFile ); #ifdef LMMS_BUILD_WIN32 char * f = qstrdup( file.toLocal8Bit().constData() ); #else char * f = qstrdup( file.toUtf8().constData() ); #endif int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; sample_rate_t samplerate = engine::mixer()->baseSampleRate(); m_frames = 0; const QFileInfo fileInfo( file ); if( fileInfo.size() > 100*1024*1024 ) { qWarning( "refusing to load sample files bigger " "than 100 MB" ); } else { #ifdef LMMS_HAVE_OGGVORBIS // workaround for a bug in libsndfile or our libsndfile decoder // causing some OGG files to be distorted -> try with OGG Vorbis // decoder first if filename extension matches "ogg" if( m_frames == 0 && fileInfo.suffix() == "ogg" ) { m_frames = decodeSampleOGGVorbis( f, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { m_frames = decodeSampleSF( f, fbuf, channels, samplerate ); } #ifdef LMMS_HAVE_OGGVORBIS if( m_frames == 0 ) { m_frames = decodeSampleOGGVorbis( f, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { m_frames = decodeSampleDS( f, buf, channels, samplerate ); } delete[] f; if ( m_frames == 0 ) // if still no frames, bail { // sample couldn't be decoded, create buffer containing // one sample-frame m_data = MM_ALLOC( sampleFrame, 1 ); memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; m_loopStartFrame = m_startFrame = 0; m_loopEndFrame = m_endFrame = 1; } else // otherwise normalize sample rate { normalizeSampleRate( samplerate, _keep_settings ); } } } else { // neither an audio-file nor a buffer to copy from, so create // buffer containing one sample-frame m_data = MM_ALLOC( sampleFrame, 1 ); memset( m_data, 0, sizeof( *m_data ) ); m_frames = 1; m_loopStartFrame = m_startFrame = 0; m_loopEndFrame = m_endFrame = 1; } if( lock ) { m_varLock.unlock(); } emit sampleUpdated(); }
( *it )->resize( _new_tempo ); } } NotePlayHandle ** NotePlayHandleManager::s_available; QReadWriteLock NotePlayHandleManager::s_mutex; AtomicInt NotePlayHandleManager::s_availableIndex; int NotePlayHandleManager::s_size; void NotePlayHandleManager::init() { s_available = MM_ALLOC( NotePlayHandle*, INITIAL_NPH_CACHE ); NotePlayHandle * n = MM_ALLOC( NotePlayHandle, INITIAL_NPH_CACHE ); for( int i=0; i < INITIAL_NPH_CACHE; ++i ) { s_available[ i ] = n; ++n; } s_availableIndex = INITIAL_NPH_CACHE - 1; s_size = INITIAL_NPH_CACHE; } NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrack, const f_cnt_t offset, const f_cnt_t frames, const Note& noteToPlay,
void LadspaEffect::pluginInstantiation() { m_maxSampleRate = maxSamplerate( displayName() ); Ladspa2LMMS * manager = Engine::getLADSPAManager(); // Calculate how many processing units are needed. const ch_cnt_t lmms_chnls = Engine::mixer()->audioDev()->channels(); int effect_channels = manager->getDescription( m_key )->inputChannels; setProcessorCount( lmms_chnls / effect_channels ); // get inPlaceBroken property m_inPlaceBroken = manager->isInplaceBroken( m_key ); // Categorize the ports, and create the buffers. m_portCount = manager->getPortCount( m_key ); int inputch = 0; int outputch = 0; LADSPA_Data * inbuf [2]; inbuf[0] = NULL; inbuf[1] = NULL; for( ch_cnt_t proc = 0; proc < processorCount(); proc++ ) { multi_proc_t ports; for( int port = 0; port < m_portCount; port++ ) { port_desc_t * p = new PortDescription; p->name = manager->getPortName( m_key, port ); p->proc = proc; p->port_id = port; p->control = NULL; p->buffer = NULL; // Determine the port's category. if( manager->isPortAudio( m_key, port ) ) { if( p->name.toUpper().contains( "IN" ) && manager->isPortInput( m_key, port ) ) { p->rate = CHANNEL_IN; p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() ); inbuf[ inputch ] = p->buffer; inputch++; } else if( p->name.toUpper().contains( "OUT" ) && manager->isPortOutput( m_key, port ) ) { p->rate = CHANNEL_OUT; if( ! m_inPlaceBroken && inbuf[ outputch ] ) { p->buffer = inbuf[ outputch ]; outputch++; } else { p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() ); m_inPlaceBroken = true; } } else if( manager->isPortInput( m_key, port ) ) { p->rate = AUDIO_RATE_INPUT; p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() ); } else { p->rate = AUDIO_RATE_OUTPUT; p->buffer = MM_ALLOC( LADSPA_Data, Engine::mixer()->framesPerPeriod() ); } } else { p->buffer = MM_ALLOC( LADSPA_Data, 1 ); if( manager->isPortInput( m_key, port ) ) { p->rate = CONTROL_RATE_INPUT; } else { p->rate = CONTROL_RATE_OUTPUT; } } p->scale = 1.0f; if( manager->isPortToggled( m_key, port ) ) { p->data_type = TOGGLED; } else if( manager->isInteger( m_key, port ) ) { p->data_type = INTEGER; } else if( p->name.toUpper().contains( "(SECONDS)" ) ) { p->data_type = TIME; p->scale = 1000.0f; int loc = p->name.toUpper().indexOf( "(SECONDS)" ); p->name.replace( loc, 9, "(ms)" ); } else if( p->name.toUpper().contains( "(S)" ) ) { p->data_type = TIME; p->scale = 1000.0f; int loc = p->name.toUpper().indexOf( "(S)" ); p->name.replace( loc, 3, "(ms)" ); } else if( p->name.toUpper().contains( "(MS)" ) ) { p->data_type = TIME; int loc = p->name.toUpper().indexOf( "(MS)" ); p->name.replace( loc, 4, "(ms)" ); } else { p->data_type = FLOATING; } // Get the range and default values. p->max = manager->getUpperBound( m_key, port ); if( p->max == NOHINT ) { p->max = p->name.toUpper() == "GAIN" ? 10.0f : 1.0f; } if( manager->areHintsSampleRateDependent( m_key, port ) ) { p->max *= m_maxSampleRate; } p->min = manager->getLowerBound( m_key, port ); if( p->min == NOHINT ) { p->min = 0.0f; } if( manager->areHintsSampleRateDependent( m_key, port ) ) { p->min *= m_maxSampleRate; } p->def = manager->getDefaultSetting( m_key, port ); if( p->def == NOHINT ) { if( p->data_type != TOGGLED ) { p->def = ( p->min + p->max ) / 2.0f; } else { p->def = 1.0f; } } else if( manager->areHintsSampleRateDependent( m_key, port ) ) { p->def *= m_maxSampleRate; } p->max *= p->scale; p->min *= p->scale; p->def *= p->scale; p->value = p->def; p->suggests_logscale = manager->isLogarithmic( m_key, port ); ports.append( p ); // For convenience, keep a separate list of the ports that are used // to control the processors. if( p->rate == AUDIO_RATE_INPUT || p->rate == CONTROL_RATE_INPUT ) { p->control_id = m_portControls.count(); m_portControls.append( p ); } } m_ports.append( ports ); } // Instantiate the processing units. m_descriptor = manager->getDescriptor( m_key ); if( m_descriptor == NULL ) { QMessageBox::warning( 0, "Effect", "Can't get LADSPA descriptor function: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setOkay( false ); return; } if( m_descriptor->run == NULL ) { QMessageBox::warning( 0, "Effect", "Plugin has no processor: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setDontRun( true ); } for( ch_cnt_t proc = 0; proc < processorCount(); proc++ ) { LADSPA_Handle effect = manager->instantiate( m_key, m_maxSampleRate ); if( effect == NULL ) { QMessageBox::warning( 0, "Effect", "Can't get LADSPA instance: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setOkay( false ); return; } m_handles.append( effect ); } // Connect the ports. for( ch_cnt_t proc = 0; proc < processorCount(); proc++ ) { for( int port = 0; port < m_portCount; port++ ) { port_desc_t * pp = m_ports.at( proc ).at( port ); if( !manager->connectPort( m_key, m_handles[proc], port, pp->buffer ) ) { QMessageBox::warning( 0, "Effect", "Failed to connect port: " + m_key.second, QMessageBox::Ok, QMessageBox::NoButton ); setDontRun( true ); return; } } } // Activate the processing units. for( ch_cnt_t proc = 0; proc < processorCount(); proc++ ) { manager->activate( m_key, m_handles[proc] ); } m_controls = new LadspaControls( this ); }