bool setCutoff( int instrumentNumber, int value ) { //helper function to set cutOff levels Hydrogen *engine = Hydrogen::get_instance(); Song *song = engine->getSong(); InstrumentList *instrList = song->get_instrument_list(); Instrument *instr = instrList->get( instrumentNumber ); if ( instr == NULL) return false; if( value != 0 ){ instr->set_filter_cutoff( (float) (value / 127.0 ) ); } else { instr->set_filter_cutoff( 0 ); } Hydrogen::get_instance()->setSelectedInstrumentNumber( instrList->index(instr) ); return true; }
bool setInstrumentPitch( int instrumentNumber, int value ) { //helper function to set cutOff levels Hydrogen *engine = Hydrogen::get_instance(); Song *song = engine->getSong(); InstrumentList *instrList = song->get_instrument_list(); Instrument *instr = instrList->get( instrumentNumber ); if ( instr == NULL) return false; if( value < 63 ){ instr->set_instrument_pitch( (float) ((value-62) / 62.0 * MAX_INSTRUMENT_PITCH ) ); } else if ( value > 64 ) { instr->set_instrument_pitch( (float) ((value-65) / 62.0 * MAX_INSTRUMENT_PITCH ) ); } else { instr->set_instrument_pitch( 0 ); } Hydrogen::get_instance()->setSelectedInstrumentNumber( instrList->index(instr) ); return true; }
void SMFWriter::save( const QString& sFilename, Song *pSong ) { INFOLOG( "save" ); const int DRUM_CHANNEL = 9; vector<SMFEvent*> eventList; SMF smf; // Standard MIDI format 1 files should have the first track being the tempo map // which is a track that contains global meta events only. SMFTrack *pTrack0 = new SMFTrack(); pTrack0->addEvent( new SMFCopyRightNoticeMetaEvent( pSong->__author , 0 ) ); pTrack0->addEvent( new SMFTrackNameMetaEvent( pSong->__name , 0 ) ); pTrack0->addEvent( new SMFSetTempoMetaEvent( pSong->__bpm , 0 ) ); pTrack0->addEvent( new SMFTimeSignatureMetaEvent( 4 , 4 , 24 , 8 , 0 ) ); smf.addTrack( pTrack0 ); // Standard MIDI Format 1 files should have note events in tracks =>2 SMFTrack *pTrack1 = new SMFTrack(); smf.addTrack( pTrack1 ); AutomationPath *vp = pSong->get_velocity_automation_path(); InstrumentList *iList = pSong->get_instrument_list(); // ogni pattern sara' una diversa traccia int nTick = 1; for ( unsigned nPatternList = 0 ; nPatternList < pSong->get_pattern_group_vector()->size() ; nPatternList++ ) { // infoLog( "[save] pattern list pos: " + toString( nPatternList ) ); PatternList *pPatternList = ( *(pSong->get_pattern_group_vector()) )[ nPatternList ]; int nStartTicks = nTick; int nMaxPatternLength = 0; for ( unsigned nPattern = 0 ; nPattern < pPatternList->size() ; nPattern++ ) { Pattern *pPattern = pPatternList->get( nPattern ); // infoLog( " |-> pattern: " + pPattern->getName() ); if ( ( int )pPattern->get_length() > nMaxPatternLength ) { nMaxPatternLength = pPattern->get_length(); } for ( unsigned nNote = 0; nNote < pPattern->get_length(); nNote++ ) { const Pattern::notes_t* notes = pPattern->get_notes(); FOREACH_NOTE_CST_IT_BOUND(notes,it,nNote) { Note *pNote = it->second; if ( pNote ) { float rnd = (float)rand()/(float)RAND_MAX; if ( pNote->get_probability() < rnd ) { continue; } float fPos = nPatternList + (float)nNote/(float)nMaxPatternLength; float velocity_adjustment = vp->get_value(fPos); int nVelocity = (int)( 127.0 * pNote->get_velocity() * velocity_adjustment ); int nInstr = iList->index(pNote->get_instrument()); Instrument *pInstr = pNote->get_instrument(); int nPitch = pNote->get_midi_key(); eventList.push_back( new SMFNoteOnEvent( nStartTicks + nNote, DRUM_CHANNEL, nPitch, nVelocity ) ); int nLength = 12; if ( pNote->get_length() != -1 ) { nLength = pNote->get_length(); } eventList.push_back( new SMFNoteOffEvent( nStartTicks + nNote + nLength, DRUM_CHANNEL, nPitch, nVelocity ) ); } } } } nTick += nMaxPatternLength; }