2014-09-16 3 views
2

Я работал в проекте, где мне нужно манипулировать каждым инструментом в файле MIDI в java. Затем я решил получить каждое MIDI-событие из каждой дорожки из последовательности и отправить его в приемник. После этого поток ждет времени, в течение которого будет продолжаться каждый тик, а затем повторите это с помощью следующего тика. Проблема в том, что звук инструментов очень запутан, а также их порядок. Я тоже пытался выполнить каждый трек, но он все еще испорчен! Код:MIDI Java генерирует беспорядочный звук

Sequence sequence  = MidiSystem.getSequence(new File(source)); 
    Synthesizer synth   = MidiSystem.getSynthesizer(); 

    //Gets a MidiMessage and send it to Synthesizer 
    Receiver rcv    = synth.getReceiver(); 

    //Contains all tracks and events from MIDI file 
    Track[]  tracks   = sequence.getTracks(); 
    synth.open(); 

    //If there are tracks 
    if(tracks != null) 
    { 
     //Verify the division type of the sequence (PPQ, SMPT) 
     if(sequence.getDivisionType() == Sequence.PPQ) 
     { 
      int  ppq   = sequence.getResolution(); 
      //Do the math to get the time (in miliseconds) each tick takes 
      long tickTime = TicksToMiliseconds(BPM,ppq); 
      //Returns the number of ticks from the longest track 
      int  longestTrackTicks = LongestTrackTicks(tracks); 

      //Each iteration sends a new message to 'receiver' 
      for(int tick = 0; tick < maiorTick ; tick++) 
      { 
       //Iteration of each track 
       for(int trackNumber = 0; trackNumber < tracks.length; trackNumber++) 
       { 
        //If the number of ticks from a track isn't already finished 
        //continue 
        if(tick < tracks[trackNumber].size()) 
        { 
         MidiEvent ev = tracks[trackNumber].get(tick); 
         rcv.send(ev.getMessage(),-1); 
        } 
       } 
       Thread.sleep(tickTime); 
      } 

     } 
    } 
    synth.close(); 

ответ

1

Как указано в ntabee, Track.get(n) возвращает n -е событие на трек; чтобы получать события по времени, вы должны вручную сравнивать события.

Кроме того, Thread.sleep() не очень точный и может подождать больше времени, чем нужно. Эти ошибки будут складываться.


Для изменения MIDI-сообщений в режиме реального времени, скажите секвенсор, чтобы играть в свой собственный Receiver, то делать все, что вы хотите, чтобы события и передать их в «реальной» Receiver.

0

По крайней мере, ваш код выглядит как звонкий/выключить что-то в каждыеtickTime мс. период. track.get(tick) только что возвращает tick -е событие на треке, не события на данный момент от tick. Если ваша цель - просто воспроизводить звук, Java предоставляет для него API высокого уровня, см., Например, http://www.jsresources.org/examples/midi_playback_and_recording.html

+0

Проблема в том, что мне нужно манипулировать инструментами во время воспроизведения музыки. Вот почему я раньше не использовал секвенсор. Идея состоит в том, чтобы изменить громкость некоторых инструментов во время их воспроизведения. Кроме того, track.get (tick) возвращает документацию MIDI Event.Java, в которой говорится, что MIDI Event имеет MIDI-сообщение, и в нем содержится вся информация об звуке на этом тике. –

0

Я решил использовать секвенсор. Я не знал, но метод «запуска» запускается в новом потоке, и пока он все еще работает, я могу отключить каждый инструмент, который я хочу, и это именно то, что я хотел. Спасибо за ответы!

Смежные вопросы