|
From: Bantai <ba...@us...> - 2007-09-09 11:14:23
|
Update of /cvsroot/xrns-php/xrns-php/scripts In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv11440 Modified Files: xrns2midi.cfg xrns2midi.php xrns2midi_classes.php Log Message: XRNS2MIDI v0.20 Index: xrns2midi.cfg =================================================================== RCS file: /cvsroot/xrns-php/xrns-php/scripts/xrns2midi.cfg,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** xrns2midi.cfg 25 Aug 2007 22:37:43 -0000 1.2 --- xrns2midi.cfg 6 Sep 2007 21:22:57 -0000 1.3 *************** *** 1,4 **** [config] ! caption=XRNS2MIDI Alpha 0.19 author=Coded by Marvin Tjon (Bantai) url=http://xrns-php.sourceforge.net/xrns2midi.html --- 1,4 ---- [config] ! caption=XRNS2MIDI Alpha 0.20 author=Coded by Marvin Tjon (Bantai) url=http://xrns-php.sourceforge.net/xrns2midi.html Index: xrns2midi_classes.php =================================================================== RCS file: /cvsroot/xrns-php/xrns-php/scripts/xrns2midi_classes.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** xrns2midi_classes.php 25 Aug 2007 22:37:44 -0000 1.2 --- xrns2midi_classes.php 6 Sep 2007 21:22:57 -0000 1.3 *************** *** 1,7 **** <?php ! // XRNS2MID version 0.19 by Marvin Tjon (Bantai) // ! // Last saved on 26 Aug 2007 // Based on XRNS2MID version 0.03 by Dac Chartrand // --- 1,7 ---- <?php ! // XRNS2MID version 0.20 by Marvin Tjon (Bantai) // ! // Last saved on 6 Sep 2007 // Based on XRNS2MID version 0.03 by Dac Chartrand // *************** *** 220,224 **** * @return Array[MidiEvents] */ ! function getEvents() { $this->sortEvents(); --- 220,224 ---- * @return Array[MidiEvents] */ ! function &getEvents() { $this->sortEvents(); *************** *** 243,247 **** $evt->col = $col; $this->events[$pos][$tick][$col][] = $evt; ! if ($evt->type == 1) //note-on { MasterTrack::setLastNote($col, $evt); --- 243,247 ---- $evt->col = $col; $this->events[$pos][$tick][$col][] = $evt; ! if ($evt->evttype == 1 || $evt->evttype == 2) //note-on && note-off { MasterTrack::setLastNote($col, $evt); *************** *** 368,371 **** --- 368,372 ---- public $division = 96; // MIDI clicks per quarter note public $lpb = 4; //initial lpb + public $timestamp = 0; //initial timestamp //global pattern effects *************** *** 391,395 **** self::$midi->open(); self::$midi->newTrack(); ! self::$midi->setTimebase(96); $this->notes = self::$midi->getNoteList(); } --- 392,396 ---- self::$midi->open(); self::$midi->newTrack(); ! self::$midi->setTimebase($this->division); $this->notes = self::$midi->getNoteList(); } *************** *** 492,496 **** */ function setRealBpm($pos, $realbpm) ! { $this->addEventArr($pos,0, 0, 9, array('num' => (int)floor(60000000 / $realbpm))); } --- 493,498 ---- */ function setRealBpm($pos, $realbpm) ! { ! $this->globals['realbpm'][$pos] = $realbpm; $this->addEventArr($pos,0, 0, 9, array('num' => (int)floor(60000000 / $realbpm))); } *************** *** 546,550 **** } else if ($pos > 0) { ! $haystack = array_reverse($this->globals[$param], true); $prev_key = 0; foreach ($haystack as $key => $val) --- 548,554 ---- } else if ($pos > 0) { ! //$haystack = array_reverse($this->globals[$param], true); ! krsort($this->globals[$param]); ! $haystack = $this->globals[$param]; $prev_key = 0; foreach ($haystack as $key => $val) *************** *** 590,601 **** function getNextGlobal($pos, $param) { if ($pos < 0) $pos = 0; $arr = array_keys($this->globals[$param]); $a = max($arr); for ($i=$pos;$i<=$a;$i++) if (isset($this->globals[$param][$i])) ! return new Globals($i, $this->globals[$param][$i]); ! return false; } --- 594,621 ---- function getNextGlobal($pos, $param) { + + if ($pos < 0) $pos = 0; + if (isset($this->globals[$param][$pos])) + { + return new Globals(floor($pos), $this->globals[$param][$pos]); + } + ksort($this->globals[$param]); + foreach ($this->globals[$param] as $key => $val) + if ($key >= $pos) + return new Globals($pos, $val); + + return false; + + /* if ($pos < 0) $pos = 0; + $arr = array_keys($this->globals[$param]); $a = max($arr); for ($i=$pos;$i<=$a;$i++) if (isset($this->globals[$param][$i])) ! return new Globals($i, $this->globals[$param][$i]); ! return false; ! */ } *************** *** 638,646 **** //only write if changed ! if ($pos == 0 || $this->getPreviousGlobal($pos-1, 'bpm')->val != $realbpm) $this->setRealBpm($pos, $realbpm); ! $this->globals['timestamp'][$pos] = $this->getTime($pos); } --- 658,666 ---- //only write if changed ! if ($pos == 0 || $this->getPreviousGlobal($pos-1, 'realbpm')->val != $realbpm) $this->setRealBpm($pos, $realbpm); ! $this->globals['timestamp'][$pos] = $this->getTimeStamp($pos, 0); } *************** *** 671,686 **** * @return int */ function getTime($pos) { ! if ($prevTimeStamp = $this->getPreviousGlobal($pos-1, 'timestamp')) { $prevLpb = $this->getPreviousGlobal($pos-1, 'lpb'); ! $resolution = ($this->division / $prevLpb->val); $time = $prevTimeStamp->val + $resolution * ($pos - $prevTimeStamp->pos); } ! else { ! $prevLpb = $this->getDefaultGlobal('lpb'); $resolution = ($this->division / $prevLpb->val); $time = $resolution * $pos; --- 691,712 ---- * @return int */ + /* function getTime($pos) { ! if (isset($this->globals['timestamp'][$pos])) ! { ! return $this->globals['timestamp'][$pos]; ! } ! //We need the most recent timestamp to base the current one on ! elseif ($prevTimeStamp = $this->getPreviousGlobal($pos-1, 'timestamp')) { $prevLpb = $this->getPreviousGlobal($pos-1, 'lpb'); ! $resolution = ($this->division / $prevLpb->val); $time = $prevTimeStamp->val + $resolution * ($pos - $prevTimeStamp->pos); } ! else //If not, simply count from line 0 { ! $prevLpb = $this->getPreviousGlobal($pos, 'lpb'); $resolution = ($this->division / $prevLpb->val); $time = $resolution * $pos; *************** *** 688,692 **** return (int) round($time); } ! /** * Calculates absolute midi timestamp from tracker line at current speed. --- 714,718 ---- return (int) round($time); } ! /* /** * Calculates absolute midi timestamp from tracker line at current speed. *************** *** 699,702 **** --- 725,729 ---- * @return int */ + /* function getTimestamp($pos, $offset) { *************** *** 714,717 **** --- 741,769 ---- return $this->getTime($pos); } + */ + function getTimestamp($pos, $offset) + { + $t3 = 0; + + if ($offset != 0) + { + $lpb2 = $this->getPreviousGlobal($pos, 'lpb'); + $speed2 = $this->getPreviousGlobal($pos, 'speed'); + $reso2 = ($this->division / $lpb2->val); + $t3 = $reso2 * ($offset / $speed2->val); + } + elseif (isset($this->globals['timestamp'][$pos])) + return $this->globals['timestamp'][$pos]; + + $t1 = $this->getPreviousGlobal($pos-1, 'timestamp'); + $lpb1 = $this->getPreviousGlobal($pos-1, 'lpb'); + $reso1 = ($this->division / $lpb1->val); + $t2 = ($pos - $t1->pos) * $reso1; + + $time = (int)$t1->val + $t2 + $t3; + + return $time; + } + /** *************** *** 742,748 **** //TODO: note delay for note-offs //TODO: double retrigs ! //TODO: http://tutorials.renoise.com/?n=Renoise.DelayCutTrick ! if($lastnote->evttype == 2) ! return; if ($vol) //does the SimpleXML object contain a volume value? --- 794,800 ---- //TODO: note delay for note-offs //TODO: double retrigs ! //Done: http://tutorials.renoise.com/?n=Renoise.DelayCutTrick ! //if($lastnote->evttype == 2) ! // return; if ($vol) //does the SimpleXML object contain a volume value? *************** *** 752,757 **** //set default to remove any values (that can be interpreted as fx) // outside midi range, since we are already handling fx here ! $lastnote->vol = 0x7F; ! $lastnote->pan = 0x40; //Note volume (0 - 7F, 80) --- 804,808 ---- //set default to remove any values (that can be interpreted as fx) // outside midi range, since we are already handling fx here ! $lastnote->vol = 0x7F; //Note volume (0 - 7F, 80) *************** *** 782,798 **** if ($pan) //does the SimpleXML object contain a panning value? ! { if ($pan <= 0x80) ! $lastnote->pan = (int) intval((string) $pan, 16); //Delay note X ticks (D0 - DF) //Only valid if ticks < speed; check in getTimeStamp() ! elseif ($vol > 0xD0 && $vol <= 0xDF) ! $lastnote->offset = $vol - 0xD0; //Retrig note X ticks (E0 - EF) //Notes = ceil(speed / X); X(0) = 1; ! elseif ($vol > 0xE0 && $vol <= 0xEF) ! $lastnote->retrig = $vol - 0xE0; } } --- 833,863 ---- if ($pan) //does the SimpleXML object contain a panning value? ! { ! $pan = (int) intval((string) $pan, 16); ! ! //set default to remove any values (that can be interpreted as fx) ! // outside midi range, since we are already handling fx here ! $lastnote->pan = 0x40; ! if ($pan <= 0x80) ! $lastnote->pan = (int) intval((string) $pan, 16); //Delay note X ticks (D0 - DF) //Only valid if ticks < speed; check in getTimeStamp() ! elseif ($pan > 0xD0 && $pan <= 0xDF) ! $lastnote->offset = $pan - 0xD0; //Retrig note X ticks (E0 - EF) //Notes = ceil(speed / X); X(0) = 1; ! elseif ($pan > 0xE0 && $pan <= 0xEF) ! $lastnote->retrig = $pan - 0xE0; ! ! //Cut Note after X Ticks (F0 - FE) ! elseif ($pan > 0xF0 && $pan <= 0xFE) ! { ! $evt = clone $lastnote; ! $evt->evttype = 2; ! MidiList::getTrack($evt->inst)->addEvent($pos, $pan-0xF0, $evt->col, $evt); ! } } } Index: xrns2midi.php =================================================================== RCS file: /cvsroot/xrns-php/xrns-php/scripts/xrns2midi.php,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xrns2midi.php 26 Aug 2007 12:03:59 -0000 1.4 --- xrns2midi.php 6 Sep 2007 21:22:57 -0000 1.5 *************** *** 1,7 **** <?php ! // XRNS2MID version 0.19 by Marvin Tjon (Bantai) // ! // Last saved on 26 Aug 2007 // Based on XRNS2MID version 0.03 by Dac Chartrand // --- 1,7 ---- <?php ! // XRNS2MID version 0.20 by Marvin Tjon (Bantai) // ! // Last saved on 6 Sep 2007 // Based on XRNS2MID version 0.03 by Dac Chartrand // *************** *** 90,95 **** else { //Specify manually ! $xrns_file = "C:/[bb5entries]/test/ogg.xrns"; ! $mid_file = "C:/[bb5entries]/test/ogg.019.mid"; if (!file_exists($xrns_file)) die("Error: Input file not found.\n"); --- 90,95 ---- else { //Specify manually ! $xrns_file = "C:/[bb5entries]/test/note-off.xrns"; ! $mid_file = "C:/[bb5entries]/test/note-off.020.mid"; if (!file_exists($xrns_file)) die("Error: Input file not found.\n"); *************** *** 126,129 **** --- 126,130 ---- echo "XRNS Document Version: " . $doc_version = $sx['doc_version'] . "\n\n"; if ($schema_check) + { if (!xrns_xsd_check($sx, $doc_version)) { *************** *** 131,134 **** --- 132,137 ---- die("\n". $xrns_file . " failed to validate against schema. The song appears to be broken.\n\n" ); } + echo "\n"; + } *************** *** 191,195 **** //$patternid = (int)$sx->PatternSequence->PatternSequence->Pattern[$pn]; if (isset($p->Name)) $patternName = (string)$p->Name; else $patternName = ''; ! echo "\n Parsing pattern [$pn]: $patternid $patternName... \n"; $master->addEventArr($lines,0, 0,11,array('type'=>'Marker', 'string'=>"Pattern [$pn]: $patternid $patternName")); foreach (array($p->Tracks->PatternTrack,$p->Tracks->PatternMasterTrack, $p->Tracks->PatternSendTrack) as $tx) --- 194,198 ---- //$patternid = (int)$sx->PatternSequence->PatternSequence->Pattern[$pn]; if (isset($p->Name)) $patternName = (string)$p->Name; else $patternName = ''; ! echo " Parsing pattern [$pn]: $patternid $patternName... \n"; $master->addEventArr($lines,0, 0,11,array('type'=>'Marker', 'string'=>"Pattern [$pn]: $patternid $patternName")); foreach (array($p->Tracks->PatternTrack,$p->Tracks->PatternMasterTrack, $p->Tracks->PatternSendTrack) as $tx) *************** *** 244,248 **** $lnF = MasterTrack::getLastNote($n_column); //find last note originating from this note-column ! if ($lnF !== false) //if there is a new note with instr number and there is a note before it { //OPTION: NNA forced note-off by any subsequent note in the note-column --- 247,251 ---- $lnF = MasterTrack::getLastNote($n_column); //find last note originating from this note-column ! if ($lnF !== false && $lnF->evttype != 2) //if there is a new note with instr number and there is a note before it { //OPTION: NNA forced note-off by any subsequent note in the note-column *************** *** 252,255 **** --- 255,259 ---- $evt->vol = 0; //another way to set note-off $evt->setOffset(0); + $evt->retrig = null; if (false) //bypass note-off offset for now { *************** *** 269,273 **** // Off Note; ignore note-offs at beginning of midicol $lnF = MasterTrack::getLastNote($n_column); //find last note originating from this note-column ! if ($lnF !== false) //if there is a new note with instr number and there is a note before it { $evt = clone $lnF; //make a copy of the last note --- 273,277 ---- // Off Note; ignore note-offs at beginning of midicol $lnF = MasterTrack::getLastNote($n_column); //find last note originating from this note-column ! if ($lnF !== false && $lnF->evttype != 2) //if there is a new note with instr number and there is a note before it { $evt = clone $lnF; //make a copy of the last note *************** *** 401,463 **** { $id = $miditrack->id; ! echo " Sending events for MidiTrack $id...\n"; foreach ($miditrack as $pos=>&$ticks) ! { foreach ($ticks as $tick=>&$events) ! foreach ($events as &$subevents) ! foreach ($subevents as $evtnum=>&$evt) ! { ! $timestamp = $master->getTimeStamp($pos,$tick); ! ! //note-delay ! //if offset is valid, move event to tick position ! //if offset exceeds speed, do event on this tick, further down this loop ! if ($evt->offset) ! { ! $offset = $evt->offset; ! $evt->offset = 0; ! $speed = $master->getNearestGlobal($pos, 'speed')->val; ! if ($speed > $offset) ! { ! $miditrack->addEvent($pos, $offset, $evt->col, $evt); ! continue; ! } ! } ! ! //everything that comes after this needs this timestamp ! $evt->setTimestamp($timestamp); ! ! //retrigger ! if ($evt->retrig && $evt->evttype != 2) ! { ! $retrig = $evt->retrig; ! $evt->retrig = 0; ! $speed = $master->getNearestGlobal($pos, 'speed')->val; ! if ($speed > $retrig) ! { ! $offset = 0; ! $ticksleft = $speed; ! while($ticksleft > 0) ! { ! if (isset($lastevt)) ! { ! $lastevt->evttype = 2; ! $lastevt->timestamp = $evt->timestamp; ! $miditrack->addEvent($pos, $offset, $evt->col, $lastevt); ! } ! if ($offset == 0) ! MasterTrack::$midi->addMsg($id, $evt->getMsg()); ! else ! $miditrack->addEvent($pos, $offset, $evt->col, $evt); ! $ticksleft -= $retrig; ! $offset += $retrig; ! $lastevt = clone $evt; ! } ! continue; //this is event is done, so skip the rest ! } ! } ! ! MasterTrack::$midi->addMsg($id, $evt->getMsg()); ! } } --- 405,484 ---- { $id = $miditrack->id; ! echo " Sending events for MidiTrack $id...\n"; foreach ($miditrack as $pos=>&$ticks) ! { ! //echo "Line: $pos \n"; ! //TODO: remove previous data foreach ($ticks as $tick=>&$events) ! { ! //echo "\tTick: $tick \n"; ! foreach ($events as &$subevents) ! { ! foreach ($subevents as $evtnum=>&$evt) ! { ! //note-delay ! //if offset is valid, move event to tick position ! //if offset exceeds speed, do event on this tick, further down this loop ! if (isset($evt->offset) && $evt->offset != 0) ! { ! $offset = $evt->offset; ! $evt->offset = 0; ! $speed = $master->getNearestGlobal($pos, 'speed')->val; ! ! if ($speed > $offset) ! { ! $ticks[$offset][$evt->col][] = $evt; ! unset($subevents[$evtnum]); ! ksort($ticks); ! continue; ! } ! } ! ! //everything that comes after this needs this timestamp ! $timestamp = $master->getTimeStamp($pos,$tick); ! $evt->setTimestamp($timestamp); ! ! //retrigger ! if (isset($evt->retrig) && $evt->retrig != 0 && $evt->evttype != 2) ! { ! $retrig = $evt->retrig; ! $evt->retrig = 0; ! $speed = $master->getNearestGlobal($pos, 'speed')->val; ! if ($speed > $retrig) ! { ! $offset = 0; ! $ticksleft = $speed; ! unset($lastevt); ! while($ticksleft > 0) ! { ! if (isset($lastevt)) ! { ! $lastevt->evttype = 2; ! $ticks[$offset][$lastevt->col][] = $lastevt; ! } ! if ($offset == 0) ! MasterTrack::$midi->addMsg($id, $evt->getMsg()); ! else ! { ! $ticks[$offset][$evt->col][] = $evt; ! } ! ! $ticksleft -= $retrig; ! $offset += $retrig; ! $lastevt = clone $evt; ! } ! ksort($ticks); ! unset($subevents[$evtnum]); ! continue; //this is event is done, so skip the rest ! } ! } ! MasterTrack::$midi->addMsg($id, $evt->getMsg()); ! unset($subevents[$evtnum]); ! } ! //unset($subevents); ! } ! //unset($events); ! } ! //unset($ticks); } |