예제 #1
0
 private function makeNotes(MidiSequenceHelper $sHelper, Channel $channel, Track $track, Beat $beat, Tempo $tempo, $mIndex, $bIndex, $startMove, $stroke)
 {
     for ($vIndex = 0; $vIndex < $beat->countVoices(); $vIndex++) {
         $voice = $beat->getVoice($vIndex);
         $tickHelper = $this->checkTripletFeel($voice, $bIndex);
         for ($noteIdx = 0; $noteIdx < $voice->countNotes(); $noteIdx++) {
             $note = $voice->getNote($noteIdx);
             if (!$note->isTiedNote()) {
                 $key = $this->transpose + $track->getOffset() + $note->getValue() + $track->getStrings()[$note->getString() - 1]->getValue();
                 $start = $this->applyStrokeStart($note, $tickHelper->getStart() + $startMove, $stroke);
                 $duration = $this->applyStrokeDuration($note, $this->getRealNoteDuration($sHelper, $track, $note, $tempo, $tickHelper->getDuration(), $mIndex, $bIndex), $stroke);
                 $velocity = $this->getRealVelocity($sHelper, $note, $track, $channel, $mIndex, $bIndex);
                 $channelId = $channel->getChannelId();
                 $midiVoice = $note->getString();
                 $bendMode = false;
                 $percussionChannel = $channel->isPercussionChannel();
                 //---Fade In---
                 if ($note->getEffect()->isFadeIn()) {
                     $this->makeFadeIn($sHelper, $track->getNumber(), $start, $duration, $channelId);
                 }
                 //---Grace---
                 if ($note->getEffect()->isGrace() && !$percussionChannel) {
                     $bendMode = true;
                     $graceKey = $track->getOffset() + $note->getEffect()->getGrace()->getFret() + $track->getStrings()[$note->getString() - 1]->getValue();
                     $graceLength = $note->getEffect()->getGrace()->getDurationTime();
                     $graceVelocity = $note->getEffect()->getGrace()->getDynamic();
                     $graceDuration = $note->getEffect()->getGrace()->isDead() ? $this->applyStaticDuration($tempo, self::DEFAULT_DURATION_DEAD, $graceLength) : $graceLength;
                     if ($note->getEffect()->getGrace()->isOnBeat() || $start - $graceLength < Duration::QUARTER_TIME) {
                         $start += $graceLength;
                         $duration -= $graceLength;
                     }
                     $this->makeNote($sHelper, $track->getNumber(), $graceKey->start - $graceLength, $graceDuration, $graceVelocity, $channelId, $bendMode);
                 }
                 //---Trill---
                 if ($note->getEffect()->isTrill() && !$percussionChannel) {
                     $trillKey = $track->getOffset() + $note->getEffect()->getTrill()->getFret() + $track->getStrings()[$note->getString() - 1]->getValue();
                     $trillLength = $note->getEffect()->getTrill()->getDuration()->getTime();
                     $realKey = true;
                     $tick = $start;
                     while (true) {
                         if ($tick + 10 >= $start + $duration) {
                             break;
                         } else {
                             if ($tick + $trillLength >= $start + $duration) {
                                 $trillLength = $start + $duration - $tick - 1;
                             }
                         }
                         $this->makeNote($sHelper, $track->getNumber(), $realKey ? $key : $trillKey, $tick, $trillLength, $velocity, $channelId, $bendMode);
                         $realKey = !$realKey;
                         $tick += $trillLength;
                     }
                     continue;
                 }
                 //---Tremolo Picking---
                 if ($note->getEffect()->isTremoloPicking()) {
                     $tpLength = $note->getEffect()->getTremoloPicking()->getDuration()->getTime();
                     $tick = $start;
                     while (true) {
                         if ($tick + 10 >= $start + $duration) {
                             break;
                         } else {
                             if ($tick + $tpLength >= $start + $duration) {
                                 $tpLength = $start + $duration - $tick - 1;
                             }
                         }
                         $this->makeNote($sHelper, $track->getNumber(), $key, $tick, $tpLength, $velocity, $channelId, $bendMode);
                         $tick += $tpLength;
                     }
                     continue;
                 }
                 //---Bend---
                 if ($note->getEffect()->isBend() && !$percussionChannel) {
                     $bendMode = true;
                     $this->makeBend($sHelper, $track->getNumber(), $start, $duration, $note->getEffect()->getBend(), $channelId, $midiVoice, $bendMode);
                 } else {
                     if ($note->getEffect()->isTremoloBar() && !$percussionChannel) {
                         $bendMode = true;
                         $this->makeTremoloBar($sHelper, $track->getNumber(), $start, $duration, $note->getEffect()->getTremoloBar(), $channelId, $midiVoice, $bendMode);
                     } else {
                         if ($note->getEffect()->isSlide() && !$percussionChannel) {
                             $bendMode = true;
                             $this->makeSlide($sHelper, $note, $track, $mIndex, $bIndex, $startMove, $channelId, $midiVoice, $bendMode);
                         } else {
                             if ($note->getEffect()->isVibrato() && !$percussionChannel) {
                                 $bendMode = true;
                                 $this->makeVibrato($sHelper, $track->getNumber(), $start, $duration, $channelId, $midiVoice, $bendMode);
                             }
                         }
                     }
                 }
                 //---Harmonic---
                 if ($note->getEffect()->isHarmonic() && !$percussionChannel) {
                     $orig = $key;
                     //Natural
                     if ($note->getEffect()->getHarmonic()->isNatural()) {
                         for ($i = 0; $i < count(EffectHarmonic::$naturalFrequencies); $i++) {
                             if ($note->getValue() % 12 == EffectHarmonic::$naturalFrequencies[$i][0] % 12) {
                                 $key = $orig + EffectHarmonic::$naturalFrequencies[$i][1] - $note->getValue();
                                 break;
                             }
                         }
                     } else {
                         if ($note->getEffect()->getHarmonic()->isSemi() && !$percussionChannel) {
                             $this->makeNote($sHelper, $track->getNumber(), min(127, orig), $start, $duration, max(Velocities::MIN_VELOCITY, $velocity - Velocities::VELOCITY_INCREMENT * 3), $channelId, $bendMode);
                         }
                         $key = $orig + EffectHarmonic::$naturalFrequencies[$note->getEffect()->getHarmonic()->getData()][1];
                     }
                     if ($key - 12 > 0) {
                         $hVelocity = max(Velocities::MIN_VELOCITY, $velocity - Velocities::VELOCITY_INCREMENT * 4);
                         $this->makeNote($sHelper, $track->getNumber(), $key - 12, $start, $duration, $hVelocity, $channelId, $bendMode);
                     }
                 }
                 //---Normal Note---
                 $this->makeNote($sHelper, $track->getNumber(), min(127, $key), $start, $duration, $velocity, $channelId, $bendMode);
             }
         }
     }
 }
예제 #2
0
 private function writeTrack(Track $track)
 {
     $channel = $this->getChannelRoute($track->getChannelId());
     $flags = 0;
     if ($this->isPercussionChannel($track->getSong(), $track->getChannelId())) {
         $flags |= 0x1;
     }
     $this->writeUnsignedByte($flags);
     $this->writeStringByte($track->getName(), 40);
     $this->writeInt(count($track->getStrings()));
     for ($i = 0; $i < 7; $i++) {
         $value = 0;
         if (count($track->getStrings()) > $i) {
             $string = $track->getStrings()[$i];
             $value = $string->getValue();
         }
         $this->writeInt($value);
     }
     $this->writeInt(1);
     $this->writeInt($channel->getChannel1() + 1);
     $this->writeInt($channel->getChannel2() + 1);
     $this->writeInt(24);
     $this->writeInt(min(max($track->getOffset(), 0), 12));
     $this->writeColor($track->getColor());
 }
예제 #3
0
 private function writeTrack(Track $track)
 {
     $channel = $this->getChannelRoute($track->getChannelId());
     $flags = 0;
     if ($this->isPercussionChannel($track->getSong(), $track->getChannelId())) {
         $flags |= 0x1;
     }
     $this->writeUnsignedByte($flags);
     $this->writeUnsignedByte(8 | $flags);
     $this->writeStringByte($track->getName(), 40);
     $this->writeInt(count($track->getStrings()));
     for ($i = 0; $i < 7; $i++) {
         $value = 0;
         if (count($track->getStrings()) > $i) {
             $string = $track->getStrings()[$i];
             $value = $string->getValue();
         }
         $this->writeInt($value);
     }
     $this->writeInt(1);
     $this->writeInt($channel->getChannel1() + 1);
     $this->writeInt($channel->getChannel2() + 1);
     $this->writeInt(24);
     $this->writeInt($track->getOffset());
     $this->writeColor($track->getColor());
     $this->writeBytes(array(67, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
 }