Пример #1
0
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();
}
Пример #2
0
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() );
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
	}
}
Пример #8
0
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();
}
Пример #9
0
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 )
	{
Пример #10
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;
}
Пример #11
0
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();
}
Пример #12
0
		( *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,
Пример #13
0
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 );
}