Ejemplo n.º 1
0
void MainForm::action_file_new()
{
	Hydrogen * pEngine = Hydrogen::get_instance();
	if ( (pEngine->getState() == STATE_PLAYING) ) {
		pEngine->sequencer_stop();
	}

	bool proceed = handleUnsavedChanges();
	if(!proceed) {
		return;
	}

	h2app->m_undoStack->clear();
	pEngine->getTimeline()->m_timelinevector.clear();
	Song * pSong = Song::get_empty_song();
	pSong->set_filename( "" );
	h2app->setSong(pSong);
	pEngine->setSelectedPatternNumber( 0 );
	h2app->getInstrumentRack()->getSoundLibraryPanel()->update_background_color();
	h2app->getSongEditorPanel()->updatePositionRuler();
	pEngine->getTimeline()->m_timelinetagvector.clear();

	// update director tags
	EventQueue::get_instance()->push_event( EVENT_METRONOME, 2 );
	// update director songname
	EventQueue::get_instance()->push_event( EVENT_METRONOME, 3 );
}
Ejemplo n.º 2
0
void SongEditorPanelTagWidget::on_okBtn_clicked()
{
	Hydrogen* engine = Hydrogen::get_instance();
	Timeline* pTimeline = engine->getTimeline();

	int patterngroupvectorsize;
	patterngroupvectorsize = engine->getSong()->get_pattern_group_vector()->size();

	//oldText list contains all old item values. we need them for undo an item 
	QStringList oldText;

	if(pTimeline->m_timelinetagvector.size() > 0){
		for (int i = 0; i < patterngroupvectorsize; i++){
			oldText << "";
		}
		for(int i = 0; i < pTimeline->m_timelinetagvector.size(); ++i){
			oldText.replace(pTimeline->m_timelinetagvector[i].m_htimelinetagbeat , pTimeline->m_timelinetagvector[i].m_htimelinetag);
		}
	}

	for( int i = 0; i < __theChangedItems.size() ; i++ )
	{
		QTableWidgetItem *newTagItem = new QTableWidgetItem();
		int songPosition = __theChangedItems.value( i ).toInt();
		newTagItem = tagTableWidget->item( songPosition, 0 );
		if ( newTagItem ) {
			SE_editTagAction *action = new SE_editTagAction(  newTagItem->text() ,oldText.value( songPosition ), songPosition );
			HydrogenApp::get_instance()->m_undoStack->push( action );
		}
	}
	accept();
}
Ejemplo n.º 3
0
void SongEditorPanelTagWidget::createTheTagTableWidget()
{
	Hydrogen* engine = Hydrogen::get_instance();
	Timeline* pTimeline = engine->getTimeline();
	int patterngroupvectorsize;
	patterngroupvectorsize = engine->getSong()->get_pattern_group_vector()->size();
	
	for( int i = 0; i < patterngroupvectorsize; i++ )
	{
		tagTableWidget->insertRow( i );
	}

	std::vector<Timeline::HTimelineTagVector> timelineTagVector = pTimeline->m_timelinetagvector;

	//read the tag vector and fill all tags into items
	if( timelineTagVector.size() > 0 ){
		for ( unsigned int t = 0; t < timelineTagVector.size(); t++ ){
			QTableWidgetItem *newTagItem = new QTableWidgetItem();
			newTagItem->setText( QString( "%1" ).arg( timelineTagVector[t].m_htimelinetag ) );
			tagTableWidget->setItem( timelineTagVector[t].m_htimelinetagbeat, 0, newTagItem );
			tagTableWidget->setCurrentItem( newTagItem );
			tagTableWidget->openPersistentEditor( newTagItem );
		}
	}

	//activate the clicked item and
	//if you click on an existing tag
	//fill in the old contend
	if( timelineTagVector.size() > 0 ){
		int vpos = -1;
		QTableWidgetItem *newTagItem2 = new QTableWidgetItem();
		newTagItem2->setText( QString( "" ) );
		for ( unsigned int t = 0; t < timelineTagVector.size(); t++ ){
			if( timelineTagVector[t].m_htimelinetagbeat == m_stimelineposition){
				vpos = t;
			}
		}

		if( vpos >-1 ){
			newTagItem2->setText( QString( "%1" ).arg( timelineTagVector[vpos].m_htimelinetag ) );
		}
		tagTableWidget->setItem( m_stimelineposition , 0, newTagItem2 );
		tagTableWidget->setCurrentItem( newTagItem2 );
		tagTableWidget->openPersistentEditor( newTagItem2 );
	}

	//add first tag
	if( timelineTagVector.size() == 0 ){
		QTableWidgetItem *newTagItem3 = new QTableWidgetItem();
		tagTableWidget->setItem( m_stimelineposition , 0, newTagItem3 );
		tagTableWidget->setCurrentItem( newTagItem3 );
		tagTableWidget->openPersistentEditor( newTagItem3 );		
	}

}
Ejemplo n.º 4
0
void SongEditorPanelBpmWidget::on_deleteBtn_clicked()
{
	Hydrogen* engine = Hydrogen::get_instance();
	Timeline* pTimeline = engine->getTimeline();

	float oldBpm = -1.0;	
	//search for an old entry
	if( pTimeline->m_timelinevector.size() >= 1 ){
		for ( int t = 0; t < pTimeline->m_timelinevector.size(); t++){
			if ( pTimeline->m_timelinevector[t].m_htimelinebeat == ( QString( lineEditBeat->text() ).toInt() ) -1 ) {
				oldBpm = pTimeline->m_timelinevector[t].m_htimelinebpm;
			}
		}
	}

	SE_deleteTimeLineAction *action = new SE_deleteTimeLineAction( lineEditBeat->text().toInt(), oldBpm );
	HydrogenApp::get_instance()->m_undoStack->push( action );
	accept();
}
Ejemplo n.º 5
0
SongEditorPanelBpmWidget::SongEditorPanelBpmWidget( QWidget* pParent, int beat )
	: QDialog( pParent )
	, Object( __class_name )
	, m_stimelineposition ( beat )
{
	setupUi( this );
	INFOLOG( "INIT" );
	setWindowTitle( trUtf8( "BPM" ) );	
	setFixedSize( width(), height() );

	lineEditBeat->setText(QString("%1").arg( m_stimelineposition + 1) );
	deleteBtn->setEnabled ( false );

	Hydrogen* engine = Hydrogen::get_instance();
	Timeline* pTimeline = engine->getTimeline();
	std::vector<Timeline::HTimelineVector> timelineVector = pTimeline->m_timelinevector;

	//restore the bpm value
	if( timelineVector.size() > 0 ){
		for ( int t = 0; t < timelineVector.size(); t++ ){
//			ERRORLOG(QString("%1 %2").arg(Hydrogen::get_instance()->m_timelinevector[t].m_htimelinebeat).arg(m_stimelineposition));
			if ( timelineVector[t].m_htimelinebeat == m_stimelineposition ) {
				lineEditBpm->setText( QString("%1").arg( timelineVector[t].m_htimelinebpm ) );
				deleteBtn->setEnabled ( true );
				return;
			}
			else
			{
				lineEditBpm->setText( QString("%1").arg( engine->getNewBpmJTM()) );
			}
		}
	}else
	{
		lineEditBpm->setText( QString("%1").arg( engine->getNewBpmJTM() ) );
	}
}
Ejemplo n.º 6
0
void PlaylistDialog::on_m_pPlaylistTree_itemDoubleClicked ()
{

	QTreeWidgetItem* m_pPlaylistItem = m_pPlaylistTree->currentItem();
	if ( m_pPlaylistItem == NULL ){
		QMessageBox::information ( this, "Hydrogen", trUtf8 ( "No Song selected!" ) );
		return;
	}
	QString selected;
	selected = m_pPlaylistItem->text ( 0 );

	QTreeWidget* m_pPlaylist = m_pPlaylistTree;
	int index = m_pPlaylist->indexOfTopLevelItem ( m_pPlaylistItem );
	Playlist::get_instance()->setSelectedSongNr( index );
	Playlist::get_instance()->setActiveSongNumber( index );

	HydrogenApp *pH2App = HydrogenApp::get_instance();
	Hydrogen *pEngine = Hydrogen::get_instance();


	if ( pEngine->getState() == STATE_PLAYING ){
		pEngine->sequencer_stop();
	}

	m_pPlayBtn->setPressed(false);

	Timeline* pTimeline = pEngine->getTimeline();
	pTimeline->m_timelinetagvector.clear();

	Song *pSong = Song::load ( selected );
	if ( pSong == NULL ){
		QMessageBox::information ( this, "Hydrogen", trUtf8 ( "Error loading song." ) );
		return;
	}

	pH2App->setSong ( pSong );
	pEngine->setSelectedPatternNumber ( 0 );

	HydrogenApp::get_instance()->getSongEditorPanel()->updatePositionRuler();
	pH2App->setStatusBarMessage( trUtf8( "Playlist: set song no. %1" ).arg( index +1 ), 5000 );

	HydrogenApp::get_instance()->getInstrumentRack()->getSoundLibraryPanel()->update_background_color();

	EventQueue::get_instance()->push_event( EVENT_METRONOME, 3 );

///exec script
///this is very very simple and only an experiment
#ifdef WIN32
	//I know nothing about windows scripts -wolke-
	return;
#else
	QString execscript;
	selected = m_pPlaylistItem->text ( 1 );
	bool execcheckbox = m_pPlaylistItem->checkState ( 2 );

	if( execcheckbox == false){
		//QMessageBox::information ( this, "Hydrogen", trUtf8 ( "No Script selected!" ));
		return;
	}

	if( execscript == "Script not used"){
		//QMessageBox::information ( this, "Hydrogen", trUtf8 ( "Script not in use!" ));
		return;
	}

	char *file;
	file = new char[ selected.length() + 1 ];
	strcpy( file , selected.toAscii() );
	int ret = std::system( file );
	delete [] file;
	return;
#endif

}
Ejemplo n.º 7
0
void* diskWriterDriver_thread( void* param )
{

		Object* __object = ( Object* )param;
	DiskWriterDriver *pDriver = ( DiskWriterDriver* )param;
		EventQueue::get_instance()->push_event( EVENT_PROGRESS, 0 );
		pDriver->setBpm( Hydrogen::get_instance()->getSong()->__bpm );
		pDriver->audioEngine_process_checkBPMChanged();
	__INFOLOG( "DiskWriterDriver thread start" );

	// always rolling, no user interaction
	pDriver->m_transport.m_status = TransportInfo::ROLLING;

	SF_INFO soundInfo;
	soundInfo.samplerate = pDriver->m_nSampleRate;
//	soundInfo.frames = -1;//getNFrames();		///\todo: da terminare
	soundInfo.channels = 2;
	//default format
	int sfformat = 0x010000; //wav format (default)
	int bits = 0x0002; //16 bit PCM (default)
	//sf_format switch
	if( pDriver->m_sFilename.endsWith(".aiff") || pDriver->m_sFilename.endsWith(".AIFF") ){
		sfformat =  0x020000; //Apple/SGI AIFF format (big endian)
	}
	if( pDriver->m_sFilename.endsWith(".flac") || pDriver->m_sFilename.endsWith(".FLAC") ){
		sfformat =  0x170000; //FLAC lossless file format
	}
	if( ( pDriver->m_nSampleDepth == 8 ) && ( pDriver->m_sFilename.endsWith(".aiff") || pDriver->m_sFilename.endsWith(".AIFF") ) ){
		bits = 0x0001; //Signed 8 bit data works with aiff
	}
	if( ( pDriver->m_nSampleDepth == 8 ) && ( pDriver->m_sFilename.endsWith(".wav") || pDriver->m_sFilename.endsWith(".WAV") ) ){
		bits = 0x0005; //Unsigned 8 bit data needed for Microsoft WAV format
	}
	if( pDriver->m_nSampleDepth == 16 ){
		bits = 0x0002; //Signed 16 bit data
	}
	if( pDriver->m_nSampleDepth == 24 ){
		bits = 0x0003; //Signed 24 bit data
	}
	if( pDriver->m_nSampleDepth == 32 ){
		bits = 0x0004; ////Signed 32 bit data
	}

	soundInfo.format =  sfformat|bits;

//	#ifdef HAVE_OGGVORBIS

	//ogg vorbis option
	if( pDriver->m_sFilename.endsWith( ".ogg" ) | pDriver->m_sFilename.endsWith( ".OGG" ) )
		soundInfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;

//	#endif


///formats
//          SF_FORMAT_WAV          = 0x010000,     /* Microsoft WAV format (little endian). */
//          SF_FORMAT_AIFF         = 0x020000,     /* Apple/SGI AIFF format (big endian). */
//          SF_FORMAT_AU           = 0x030000,     /* Sun/NeXT AU format (big endian). */
//          SF_FORMAT_RAW          = 0x040000,     /* RAW PCM data. */
//          SF_FORMAT_PAF          = 0x050000,     /* Ensoniq PARIS file format. */
//          SF_FORMAT_SVX          = 0x060000,     /* Amiga IFF / SVX8 / SV16 format. */
//          SF_FORMAT_NIST         = 0x070000,     /* Sphere NIST format. */
//          SF_FORMAT_VOC          = 0x080000,     /* VOC files. */
//          SF_FORMAT_IRCAM        = 0x0A0000,     /* Berkeley/IRCAM/CARL */
//          SF_FORMAT_W64          = 0x0B0000,     /* Sonic Foundry's 64 bit RIFF/WAV */
//          SF_FORMAT_MAT4         = 0x0C0000,     /* Matlab (tm) V4.2 / GNU Octave 2.0 */
//          SF_FORMAT_MAT5         = 0x0D0000,     /* Matlab (tm) V5.0 / GNU Octave 2.1 */
//          SF_FORMAT_PVF          = 0x0E0000,     /* Portable Voice Format */
//          SF_FORMAT_XI           = 0x0F0000,     /* Fasttracker 2 Extended Instrument */
//          SF_FORMAT_HTK          = 0x100000,     /* HMM Tool Kit format */
//          SF_FORMAT_SDS          = 0x110000,     /* Midi Sample Dump Standard */
//          SF_FORMAT_AVR          = 0x120000,     /* Audio Visual Research */
//          SF_FORMAT_WAVEX        = 0x130000,     /* MS WAVE with WAVEFORMATEX */
//          SF_FORMAT_SD2          = 0x160000,     /* Sound Designer 2 */
//          SF_FORMAT_FLAC         = 0x170000,     /* FLAC lossless file format */
//          SF_FORMAT_CAF          = 0x180000,     /* Core Audio File format */
//	    SF_FORMAT_OGG
///bits
//          SF_FORMAT_PCM_S8       = 0x0001,       /* Signed 8 bit data */
//          SF_FORMAT_PCM_16       = 0x0002,       /* Signed 16 bit data */
//          SF_FORMAT_PCM_24       = 0x0003,       /* Signed 24 bit data */
//          SF_FORMAT_PCM_32       = 0x0004,       /* Signed 32 bit data */
///used for ogg
//          SF_FORMAT_VORBIS

	if ( !sf_format_check( &soundInfo ) ) {
		__ERRORLOG( "Error in soundInfo" );
		return 0;
	}


	SNDFILE* m_file = sf_open( pDriver->m_sFilename.toLocal8Bit(), SFM_WRITE, &soundInfo );

	float *pData = new float[ pDriver->m_nBufferSize * 2 ];	// always stereo

	float *pData_L = pDriver->m_pOut_L;
	float *pData_R = pDriver->m_pOut_R;


		Hydrogen* engine = Hydrogen::get_instance();

	std::vector<PatternList*> *pPatternColumns = Hydrogen::get_instance()->getSong()->get_pattern_group_vector();
	int nColumns = pPatternColumns->size();

	int nPatternSize;
		int validBpm = engine->getSong()->__bpm;
		float oldBPM = 0;
		float ticksize = 0;
		for ( int patternposition = 0; patternposition < nColumns; ++patternposition ) {
				PatternList *pColumn = ( *pPatternColumns )[ patternposition ];
		if ( pColumn->size() != 0 ) {
			nPatternSize = pColumn->get( 0 )->get_length();
		} else {
			nPatternSize = MAX_NOTES;
				}

				ticksize = pDriver->m_nSampleRate * 60.0 /  engine->getSong()->__bpm / engine->getSong()->__resolution;
				// check pattern bpm if timeline bpm is in use
				Timeline* pTimeline = engine->getTimeline();
				if(Preferences::get_instance()->getUseTimelineBpm() ){
						if( pTimeline->m_timelinevector.size() >= 1 ){

								for ( int t = 0; t < pTimeline->m_timelinevector.size(); t++){
										if(pTimeline->m_timelinevector[t].m_htimelinebeat == patternposition &&
											pTimeline->m_timelinevector[t].m_htimelinebpm != validBpm){
												validBpm =  pTimeline->m_timelinevector[t].m_htimelinebpm;
										}

								}
						}
						pDriver->setBpm(validBpm);
						ticksize = pDriver->m_nSampleRate * 60.0 / validBpm / Hydrogen::get_instance()->getSong()->__resolution;
						pDriver->audioEngine_process_checkBPMChanged();
						engine->setPatternPos(patternposition);

						// delay needed time to calculate all rubberband samples
						if( Preferences::get_instance()->getRubberBandBatchMode() && validBpm != oldBPM ){
								EventQueue::get_instance()->push_event( EVENT_RECALCULATERUBBERBAND, -1);
								int sleepTime = Preferences::get_instance()->getRubberBandCalcTime()+1;
								while ((sleepTime = sleep(sleepTime)) > 0);
						}
						oldBPM = validBpm;

				}
				else
				{
						ticksize = pDriver->m_nSampleRate * 60.0 /  Hydrogen::get_instance()->getSong()->__bpm / Hydrogen::get_instance()->getSong()->__resolution;
						//pDriver->m_transport.m_nTickSize = ticksize;
				}


				 //here we have the pattern length in frames dependent from bpm and samplerate
				unsigned patternLengthInFrames = ticksize * nPatternSize;

				unsigned frameNumber = 0;
				int lastRun = 0;
				while ( frameNumber < patternLengthInFrames ) {

						int usedBuffer = pDriver->m_nBufferSize;

						//this will calculate the the size from -last- (end of pattern) used frame buffer,
						//which is mostly smaller than pDriver->m_nBufferSize
						if( patternLengthInFrames - frameNumber <  pDriver->m_nBufferSize ){
								lastRun = patternLengthInFrames - frameNumber;
								usedBuffer = lastRun;
						};

						frameNumber += usedBuffer;
						int ret = pDriver->m_processCallback( usedBuffer, NULL );

						for ( unsigned i = 0; i < usedBuffer; i++ ) {
								if(pData_L[i] > 1){
										pData[i * 2] = 1;
								}
								else if(pData_L[i] < -1){
										pData[i * 2] = -1;
								}else
								{
										pData[i * 2] = pData_L[i];
								}

								if(pData_R[i] > 1){
										pData[i * 2 + 1] = 1;
								}
								else if(pData_R[i] < -1){
										pData[i * 2 + 1] = -1;
								}else
								{
										pData[i * 2 + 1] = pData_R[i];
								}
						}
						int res = sf_writef_float( m_file, pData, usedBuffer );
						if ( res != ( int )usedBuffer ) {
								__ERRORLOG( "Error during sf_write_float" );
						}
				}

				// this progress bar methode is not exact but ok enough to give users a usable visible progress feedback
				float fPercent = ( float )(patternposition +1) / ( float )nColumns * 100.0;
				EventQueue::get_instance()->push_event( EVENT_PROGRESS, ( int )fPercent );
		}

	delete[] pData;
	pData = NULL;

	sf_close( m_file );

	__INFOLOG( "DiskWriterDriver thread end" );

	pthread_exit( NULL );

	return NULL;
}