From 78cc84b9bfc32dbc462136c54624f92a54e40132 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 30 Mar 2006 06:59:32 +0000 Subject: [PATCH] lot of improvements in FLP-import filter (import of notes etc. now working\!) git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@117 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 11 + configure.in | 4 +- include/song_editor.h | 2 + plugins/flp_import/flp_import.cpp | 362 +++++++++--------------------- plugins/flp_import/flp_import.h | 10 +- src/core/song_editor.cpp | 16 ++ 6 files changed, 138 insertions(+), 267 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8829fbce1..fc236e421 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-03-29 Tobias Doerffel + + * plugins/flp_import/flp_import.h: + * plugins/flp_import/flp_import.cpp: + - read text-len correctly + - do not crash when creating new pattern before actual channels are + created + - stated event 224 to be FLP_PatternData + - extract information for creating notes out of pattern-data + - add playlist-items after all is done for resizing them correctly + 2006-03-28 Tobias Doerffel * plugins/flp_import/flp_import.h: diff --git a/configure.in b/configure.in index 54d96a1d3..6f006ebcc 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.1.4-cvs20060328, tobydox/at/users/dot/sourceforge/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060328) +AC_INIT(lmms, 0.1.4-cvs20060329, tobydox/at/users/dot/sourceforge/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060329) AM_CONFIG_HEADER(config.h) diff --git a/include/song_editor.h b/include/song_editor.h index 38316be37..3fa465e7c 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -181,6 +181,8 @@ public slots: // set tempo in BPM (beats per minute) void setTempo( int _new_bpm = DEFAULT_BPM ); + void setMasterVolume( volume _vol ); + void setMasterPitch( int _master_pitch ); inline void setModified( void ) { diff --git a/plugins/flp_import/flp_import.cpp b/plugins/flp_import/flp_import.cpp index 69018bb1d..81f191146 100644 --- a/plugins/flp_import/flp_import.cpp +++ b/plugins/flp_import/flp_import.cpp @@ -31,6 +31,7 @@ #include "track_container.h" #include "instrument_track.h" #include "pattern.h" +#include "project_journal.h" #ifdef QT4 @@ -135,8 +136,6 @@ bool flpImport::tryImport( trackContainer * _tc ) return( FALSE ); } - printf( "channels: %d\n", num_channels ); - const int ppq = read16LE(); if( ppq < 0 ) { @@ -187,15 +186,20 @@ bool flpImport::tryImport( trackContainer * _tc ) return( FALSE ); } + printf( "channels: %d\n", num_channels ); + instrumentTrack * it = NULL; - pattern * p = NULL; + int current_pattern = 0; char * text = NULL; int text_len = 0; - int it_cnt = 0; + vlist i_tracks; int ev_cnt = 0; _tc->eng()->getSongEditor()->clearProject(); + const bool is_journ = _tc->eng()->getProjectJournal()->isJournalling(); + _tc->eng()->getProjectJournal()->setJournalling( FALSE ); + while( file().atEnd() == FALSE ) { @@ -207,7 +211,7 @@ bool flpImport::tryImport( trackContainer * _tc ) #else qApp->processEvents( 100 ); #endif - pd.setValue( it_cnt ); + pd.setValue( i_tracks.size() ); if( pd.wasCanceled() ) { @@ -233,16 +237,19 @@ bool flpImport::tryImport( trackContainer * _tc ) if( ev >= FLP_Text ) { text_len = data & 0x7F; + int shift = 0; while( data & 0x80 ) { data = readByte(); - text_len = ( text_len << 7 ) | ( data & 0x7F ); + //text_len = ( text_len << 7 ) | ( data & 0x7F ); + text_len = text_len | ( ( data & 0x7F ) << ( shift += 7 ) ); } delete[] text; text = new char[text_len+1]; if( readBlock( text, text_len ) <= 0 ) { - printf( "could not read string\n" ); + printf( "could not read string (len: %d)\n", + text_len ); } text[text_len] = 0; } @@ -273,6 +280,8 @@ bool flpImport::tryImport( trackContainer * _tc ) case FLP_MainVol: printf( "main-volume: %d\n", data ); + _tc->eng()->getSongEditor()->setMasterVolume( + static_cast( data ) ); break; case FLP_PatLength: @@ -294,7 +303,7 @@ bool flpImport::tryImport( trackContainer * _tc ) case FLP_MixSliceNum: printf( "mix slice num: %d\n", data ); break; - +/* case 31: case 32: case 33: @@ -302,35 +311,28 @@ bool flpImport::tryImport( trackContainer * _tc ) case 35: case 36: printf( "ev: %d data: %d\n", ev, data ); - break; + break;*/ // WORD EVENTS case FLP_NewChan: printf( "new channel\n" ); - ++it_cnt; - m_events.clear(); it = dynamic_cast( track::create( track::CHANNEL_TRACK, _tc->eng()->getBBEditor() ) ); assert( it != NULL ); + i_tracks.push_back( it ); it->loadInstrument( "tripleoscillator" ); it->toggledInstrumentTrackButton( FALSE ); break; case FLP_NewPat: - while( _tc->eng()->getBBEditor()->numOfBBs() <= - data ) - { - track::create( track::BB_TRACK, - _tc->eng()->getSongEditor() ); - } - p = dynamic_cast( - it->getTCO( data - 1 ) ); + current_pattern = data - 1; break; case FLP_Tempo: printf( "tempo: %d\n", data ); + _tc->eng()->getSongEditor()->setTempo( data ); break; case FLP_CurrentPatNum: @@ -368,12 +370,18 @@ bool flpImport::tryImport( trackContainer * _tc ) case FLP_MainPitch: printf( "main-pitch: %d\n", data ); + _tc->eng()->getSongEditor()->setMasterPitch( + data ); break; case FLP_Resonance: printf( "reso (for cur channel?): %d\n", data ); break; + case FLP_LoopBar: + printf( "loop bar: %d\n", data ); + break; + case FLP_StDel: printf( "stdel (delay?): %d\n", data ); break; @@ -396,20 +404,7 @@ bool flpImport::tryImport( trackContainer * _tc ) case FLP_PlayListItem: { - unsigned int pat_num = ( data >> 16 ) - 1; - while( _tc->eng()->getBBEditor()->numOfBBs() <= - pat_num ) - { - track::create( track::BB_TRACK, - _tc->eng()->getSongEditor() ); - } - - bbTrack * bbt = bbTrack::findBBTrack( pat_num, - _tc->eng() ); - trackContentObject * tco = bbt->addTCO( - bbt->createTCO( 0 ) ); - tco->movePosition( midiTime( ( data & 0xffff ) * - 64 ) ); + m_plItems.push_back( data ); break; } @@ -435,6 +430,13 @@ bool flpImport::tryImport( trackContainer * _tc ) // TEXT EVENTS case FLP_Text_ChanName: + if( it == NULL ) + { + printf( "!! tried to set channel name " + "but no channel was created so " + "far\n" ); + break; + } it->setName( text ); break; @@ -489,6 +491,33 @@ bool flpImport::tryImport( trackContainer * _tc ) dump_mem( text, text_len ); break; + case FLP_PatternData: + { + printf( "pattern data:\n" ); + //dump_mem( text, text_len ); + const int bpn = 20; + for( int i = 0; i*bpn < text_len; ++i ) + { + int ch = *( text + i*bpn + 6 ); + int pos = *( (int *)( text + i*bpn ) ); + int key = *( text + i*bpn + 12 ); + int len = *( (int*)( text + i*bpn + + 8 ) ); + pos /= 6; + len /= 6; + note n( NULL, len, pos ); + n.setKey( key ); + m_notes.push_back( qMakePair( + num_channels * current_pattern + ch, n ) ); + + //printf( "note on channel %d at pos %d with key %d and length %d ", (int)*((text+i*bpn+6)), *((int*)(text+i*bpc)), (int) *(text+i*bpc+12), (int) *((int*)(text+i*bpc+8))); + //printf( "note on channel %d at pos %d with key %d and length %d\n", ch, pos, key, len ); + + //dump_mem( text+i*bpn+4, bpc-4 ); + } + break; + } + default: if( ev >= FLP_Text ) { @@ -504,241 +533,50 @@ bool flpImport::tryImport( trackContainer * _tc ) } break; } -/* - // now process every event - for( eventVector::const_iterator it = m_events.begin(); - it != m_events.end(); ++it ) - { - const int tick = it->first; - const midiEvent & ev = it->second; - switch( ev.m_type ) - { - case NOTE_ON: - if( ev.key() >= - NOTES_PER_OCTAVE * OCTAVES ) - { - continue; - } - if( ev.velocity() > 0 ) - { - keys[ev.key()][0] = tick; - keys[ev.key()][1] = - ev.velocity(); - break; - } - - case NOTE_OFF: - if( ev.key() < - NOTES_PER_OCTAVE * OCTAVES && - keys[ev.key()][0] >= 0 ) - { - note n( eng(), - midiTime( ( tick - keys[ev.key()][0] ) / 10 ), - midiTime( keys[ev.key()][0] / 10 ), - (tones)( ev.key() % NOTES_PER_OCTAVE ), - (octaves)( ev.key() / NOTES_PER_OCTAVE ), - keys[ev.key()][1] * 100 / 128 ); - p->addNote( n ); - keys[ev.key()][0] = -1; - } - break; - - default: -// printf( "Unhandled event: %#x\n", -// ev.m_type ); - break; - } - }*/ } + + // now process all notes + for( patternNoteVector::const_iterator it = m_notes.begin(); + it != m_notes.end(); ++it ) + { + const int where = ( *it ).first; + const int ch = where % num_channels; + const csize pat = where / num_channels; + while( _tc->eng()->getBBEditor()->numOfBBs() <= pat ) + { + track::create( track::BB_TRACK, + _tc->eng()->getSongEditor() ); + } + pattern * p = dynamic_cast( + i_tracks[ch]->getTCO( pat ) ); + if( p != NULL ) + { + p->addNote( ( *it ).second, FALSE ); + } + } + + // process all playlist-items + for( playListItems::const_iterator it = m_plItems.begin(); + it != m_plItems.end(); ++it ) + { + unsigned int pat_num = ( ( *it ) >> 16 ) - 1; + while( _tc->eng()->getBBEditor()->numOfBBs() <= pat_num ) + { + track::create( track::BB_TRACK, + _tc->eng()->getSongEditor() ); + } + + bbTrack * bbt = bbTrack::findBBTrack( pat_num, _tc->eng() ); + trackContentObject * tco = bbt->addTCO( bbt->createTCO( 0 ) ); + tco->movePosition( midiTime( ( ( *it ) & 0xffff ) * 64 ) ); + } + + _tc->eng()->getProjectJournal()->setJournalling( is_journ ); return( TRUE ); } -#if 0 -bool FASTCALL flpImport::readTrack( int _track_end ) -{ - int tick = 0; - unsigned char last_cmd = 0; -// unsigned char port = 0; - - m_events.clear(); - // the current file position is after the track ID and length - while( (int) file().pos() < _track_end ) - { - unsigned char cmd; - int len; - - int delta_ticks = readVar(); - if( delta_ticks < 0 ) - { - break; - } - tick += delta_ticks; - - int c = readByte(); - if( c < 0 ) - { - break; - } - if( c & 0x80 ) - { - // have command - cmd = c; - if( cmd < 0xf0 ) - { - last_cmd = cmd; - } - } - else - { - // running status - ungetChar( c ); - cmd = last_cmd; - if( !cmd ) - { - error(); - return( FALSE ); - } - } - switch( cmd & 0xF0 ) - { - // channel msg with 2 parameter bytes - case NOTE_OFF: - case NOTE_ON: - case KEY_PRESSURE: - case CONTROL_CHANGE: - case PITCH_BEND: - { - int data1 = readByte() & 0x7F; - int data2 = readByte() & 0x7F; - m_events.push_back( qMakePair( tick, - midiEvent( static_cast( - cmd & 0xF0 ), - cmd & 0x0F, - data1, - data2 ) ) ); - break; - } - // channel msg with 1 parameter byte - case PROGRAM_CHANGE: - case CHANNEL_PRESSURE: - m_events.push_back( qMakePair( tick, - midiEvent( static_cast( - cmd & 0xF0 ), - cmd & 0x0F, - readByte() & 0x7F ) ) ); - break; - - case MIDI_SYSEX: - switch( cmd ) - { - case MIDI_SYSEX: - case MIDI_EOX: - { - len = readVar(); - if( len < 0 ) - { - error(); - return( FALSE ); - } - if( cmd == MIDI_SYSEX ) - { - ++len; - } - char * data = new char[len]; - if( cmd == MIDI_SYSEX ) - { - data[0] = MIDI_SYSEX; - } - for( ; c < len; ++c ) - { - data[c] = readByte(); - } - m_events.push_back( - qMakePair( tick, - midiEvent( MIDI_SYSEX, data, len ) ) ); - break; - } - - case MIDI_META_EVENT: - c = readByte(); - len = readVar(); -/* if( len < 0 ) - { - error(); - return( FALSE ); - }*/ - switch( c ) - { - case 0x21: // port number - if( len < 1 ) - { - error(); - return( FALSE ); - } -/* port = readByte() % - port_count; - skip( len - 1 );*/ - skip( len ); - break; - - case 0x2F: // end of track - //track->end_tick = tick; - skip( _track_end - - file().pos() ); - return( TRUE ); - - case 0x51: // tempo - if( len < 3 ) - { - error(); - return( FALSE ); - } - if( m_smpteTiming ) - { - // SMPTE timing - // doesnt change - skip( len ); - } - else - { -/* event = new_event(track, 0); - event->type = SND_SEQ_EVENT_TEMPO; - event->port = port; - event->tick = tick; - event->data.tempo = read_byte() << 16; - event->data.tempo |= read_byte() << 8; - event->data.tempo |= read_byte(); - skip( len -3 );*/ - skip( len ); - } - break; - - default:// ignore all other - // meta events - skip( len ); - break; - } - break; - - default: // invalid Fx command - error(); - return( FALSE ); - } - break; - - default: // cannot happen - error(); - return( FALSE ); - } - } - error(); - return( FALSE ); -} - -#endif - extern "C" diff --git a/plugins/flp_import/flp_import.h b/plugins/flp_import/flp_import.h index 9976174ad..a995f169b 100755 --- a/plugins/flp_import/flp_import.h +++ b/plugins/flp_import/flp_import.h @@ -48,8 +48,8 @@ #endif -#include "midi.h" #include "import_filter.h" +#include "note.h" enum flpEvents @@ -155,6 +155,7 @@ enum flpEvents FLP_PluginParams = FLP_Text + 21, FLP_ChanParams = FLP_Text + 23,// block of various channel // params (can grow) + FLP_PatternData = FLP_Text + 32, FLP_CmdCount @@ -244,8 +245,11 @@ private: } - typedef vvector > eventVector; - eventVector m_events; + typedef vlist > patternNoteVector; + patternNoteVector m_notes; + + typedef vlist playListItems; + playListItems m_plItems; } ; diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index 2e4c2f2a9..9a49890fc 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -739,6 +739,22 @@ void songEditor::setTempo( int _new_bpm ) +void songEditor::setMasterVolume( volume _vol ) +{ + m_masterVolumeSlider->setValue( _vol ); +} + + + + +void songEditor::setMasterPitch( int _master_pitch ) +{ + m_masterPitchSlider->setValue( _master_pitch ); +} + + + + int songEditor::masterPitch( void ) const { return( -m_masterPitchSlider->value() );