Jump to content


Photo

Merge Songs


  • Please log in to reply
185 replies to this topic

#26 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 30 May 2007 - 18:56

In case it wasn't apparent, the above code now fully merges song2 into song1, creating song3.

My problem is that this merged song crashes Renoise.

At this point, most of the work is done. We just need to work out what I'm missing, doing wrong, etc. Why not have a try at this code?

If you are on windows download ftp://ftp.info-zip.org/pub/infozip/win32/unz552xn.exe and ftp://ftp.info-zip.org/pub/infozip/win32/zip232xn.zip then put zip.exe / unzip.exe in your Windows/System32 directory (trash the other files). I opted for external binaries because compiling ZIP support in PHP5 on OS X is not trivial. Downloading 2 tiny executables that are already on every operating system in existence (except, of course, Windows) is easier to deal with. Also, create a directory called /tmp on the partition you are working on. Or, change the variable at the top of the script.

Really, I won't have time to look at this until next week. It would be really cool if a few of you could try merging some test songs and tell me where I am going wrong, because I can't see it at the moment. The more eyes, the better.

Thanks.

Disclaimer 1: Above code = see previous page.
Disclaimer 2: Do not trash System32, I mean trash the superfluous files in the zip/unzip packages.
Disclaimer 3: I am not responsible for you ruining/deleting your system with your own incompetence.

Cheers.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#27 taktik

taktik

    Renoise Developer

  • Admins
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 15040 posts
  • Gender:Male
  • Location:Berlin, Germany
  • Interests:füße waschen

Posted 30 May 2007 - 21:19

Here is a fixed version. You just forgot one foreach in the patterntrack insertion stuff - only fixed the track counts in the first patterns...

The extra "if (count($x->Tracks->PatternSendTrack))" is for the rare (but possible) case that no send tracks are available in song2.

Also fixed a small problem in the instrument shifting code.

<?php

/*

Requires: PHP5 and Info-Zip (http://www.info-zip.org/)
Usage: `php xrns_merge.php /path/to/file1.xrns /path/to/file2.xrns file3.xrns`
Will output file to current working directory

*/

// ----------------------------------------------------------------------------
// Variables
// ----------------------------------------------------------------------------

$schema = '/Applications/Renoise.app/Contents/Resources/Schemas/RenoiseSong4.xsd';
$tmp_dir = 'D:/Temp';
$unzip_xrns = 'unzip @_SRC_@ -d @_DST_@';
$zip_xrns = 'zip -r @_DST_@ .';

// ----------------------------------------------------------------------------
// Functions
// ----------------------------------------------------------------------------

function simplexml_append(SimpleXMLElement $parent, SimpleXMLElement $new_child){
	$node1 = dom_import_simplexml($parent);
	$dom_sxe = dom_import_simplexml($new_child);
	$node2 = $node1->ownerDocument->importNode($dom_sxe, true);
	$node1->appendChild($node2);
}

function simplexml_insert_before(SimpleXMLElement $parent, SimpleXMLElement $new_child, SimpleXMLElement $before){
	$node1 = dom_import_simplexml($parent);
	$dom_sxe = dom_import_simplexml($new_child);
	$node2 = $node1->ownerDocument->importNode($dom_sxe, true);
	$node1->insertBefore($node2, dom_import_simplexml($before));
}

function UnzipAllFiles($zipFile, $zipDir) {
	global $unzip_xrns;
	$unzipCmd = $unzip_xrns;
	$unzipCmd = str_replace('@_SRC_@', $zipFile, $unzipCmd);
	$unzipCmd = str_replace('@_DST_@', $zipDir, $unzipCmd);
	$res = -1; // any nonzero value
	$UnusedArrayResult = array();
	$UnusedStringResult = exec($unzipCmd, $UnusedArrayResult, $res);
	return ($res == 0);
}

function ZipAllFiles($zipFile, $zipDir) {
	global $zip_xrns;

	$tmp = getcwd(); // Change dir to get relative path
	chdir($zipDir);

	$zipCmd = $zip_xrns;
	$zipCmd = str_replace('@_DST_@', $zipFile, $zipCmd);
	$res = -1; // any nonzero value
	$UnusedArrayResult = array();
	$UnusedStringResult = exec($zipCmd, $UnusedArrayResult, $res);

	chdir($tmp); // Back to previous working directory

	if (!copy($zipDir . $zipFile, $tmp . '/' . $zipFile)) {
		die("Error: Failed to copy $zipFile...\n");
	}

	return ($res == 0);
}

function dircopy($srcdir, $dstdir, $verbose = false) {
	$num = 0;
	if(!is_dir($dstdir)) mkdir($dstdir);
	if($curdir = opendir($srcdir)) {
		while($file = readdir($curdir)) {
			if($file != '.' && $file != '..') {
				$srcfile = $srcdir . '/' . $file;
				$dstfile = $dstdir . '/' . $file;
				if(is_file($srcfile)) {
					if(is_file($dstfile)) $ow = filemtime($srcfile) - filemtime($dstfile); else $ow = 1;
					if($ow > 0) {
						if($verbose) echo "Copying '$srcfile' to '$dstfile'...";
						if(copy($srcfile, $dstfile)) {
							touch($dstfile, filemtime($srcfile)); $num++;
							if($verbose) echo "OK\n";
						}
						else die("Error: File '$srcfile' could not be copied.\n");
					}
				}
				else if(is_dir($srcfile)) {
					$num += dircopy($srcfile, $dstfile, $verbose);
				}
			}
		}
		closedir($curdir);
	}
	return $num;
}

function obliterate_directory($dirname, $only_empty = false) {
	if (!is_dir($dirname)) return false;
	$dscan = array(realpath($dirname));
	$darr = array();
	while (!empty($dscan)) {
		$dcur = array_pop($dscan);
		$darr[] = $dcur;
		if ($d = opendir($dcur)) {
			while ($f=readdir($d)) {
				if ($f == '.' || $f == '..') continue;
				$f=$dcur.'/'.$f;
				if (is_dir($f)) $dscan[] = $f;
				else unlink($f);
			}
			closedir($d);
		}
	}
	$i_until = ($only_empty)? 1 : 0;
	for ($i=count($darr)-1; $i>=$i_until; $i--) {
		if (!rmdir($darr[$i])) die("Error: There was a problem deleting a temporary file.\n");
	}
	return (($only_empty)? (count(scandir)<=2) : (!is_dir($dirname)));
}


// ----------------------------------------------------------------------------
// Check User Input
// ----------------------------------------------------------------------------

if ($argc != 4) die("Error: This script expects 3 parameters.");
if (!file_exists($argv[1])) die("Error: The file $argv[1] was not found.");
if (!file_exists($argv[2])) die("Error: The file $argv[2] was not found.");

$song1 = $argv[1];
$song2 = $argv[2];
$song3 = $argv[3];

// ----------------------------------------------------------------------------
// Unpack
// ----------------------------------------------------------------------------

echo "Working...\n";

// Create a unique directory
$unzip1 = $tmp_dir . '/xrns_merge_' . md5(uniqid(mt_rand(), true)) . '_Track01/';
$unzip2 = $tmp_dir . '/xrns_merge_' . md5(uniqid(mt_rand(), true)) . '_Track02/';

// Unzip song1
$result = UnzipAllFiles($song1, $unzip1);
if($result === FALSE) {
	die("Error: There was a problem unziping the first file.\n");
}

// Unzip song2
$result = UnzipAllFiles($song2, $unzip2);
if($result === FALSE) {
	die("Error: There was a problem unziping the second file.\n");
}

// Load XML
$sx1 = simplexml_load_file($unzip1 . 'Song.xml');
$sx2 = simplexml_load_file($unzip2 . 'Song.xml');

// ----------------------------------------------------------------------------
// Append the total tracks and sends in song2 as empty offsets to song1,
// prepend the total tracks and sends in song1 as empty offsets to song2.
// ----------------------------------------------------------------------------

$offset = count($sx1->Tracks->SequencerTrack);
$offset2 = count($sx2->Tracks->SequencerTrack);
for ($i = 0; $i < $offset; ++$i) {
	foreach ($sx2->PatternPool->Patterns->Pattern as $x) {
		simplexml_insert_before($x->Tracks,
			simplexml_load_string('<PatternTrack type="PatternTrack"/>'),
			$x->Tracks->PatternTrack[0]);
	}
}
for ($i = 0; $i < $offset2; ++$i) {
	foreach ($sx1->PatternPool->Patterns->Pattern as $x) {
		simplexml_insert_before($x->Tracks,
			simplexml_load_string('<PatternTrack type="PatternTrack"/>'),
			$x->Tracks->PatternMasterTrack);
	}
}

$offset = count($sx1->Tracks->SequencerSendTrack);
$offset2 = count($sx2->Tracks->SequencerSendTrack);
for ($i = 0; $i < $offset; ++$i) {
	foreach ($sx2->PatternPool->Patterns->Pattern as $x) {
		if (count($x->Tracks->PatternSendTrack)){
			  simplexml_insert_before($x->Tracks,
				  simplexml_load_string('<PatternSendTrack type="PatternSendTrack"/>'),
				  $x->Tracks->PatternSendTrack[0]);
		} 
		else {
			simplexml_append($x->Tracks,
				simplexml_load_string('<PatternSendTrack type="PatternSendTrack"/>'));
		}
		
	}
}
for ($i = 0; $i < $offset2; ++$i) {
	foreach ($sx1->PatternPool->Patterns->Pattern as $x) {
		simplexml_append($x->Tracks,
			simplexml_load_string('<PatternSendTrack type="PatternSendTrack"/>'));
	}
}

// ----------------------------------------------------------------------------
// Patterns in song2 are shifted the total patterns in song1, adjust the
// PatternSequence pointer offsets accordingly.
// ----------------------------------------------------------------------------

$offset = count($sx1->PatternPool->Patterns->Pattern);
for ($i = 0; $i < count($sx2->PatternSequence->PatternSequence->Pattern); ++$i) {
	$shift = str_pad(($sx2->PatternSequence->PatternSequence->Pattern[$i] + $offset), 2, '0', STR_PAD_LEFT);
	$sx2->PatternSequence->PatternSequence->Pattern[$i] = $shift;
}

// ----------------------------------------------------------------------------
// Instruments and VstiAutomationDevices in song2 are shifted the total
// instruments in song1, adjust the pointer offsets accordingly.
// Copy the instruments with these same offsets
// ----------------------------------------------------------------------------

$offset = count($sx1->Instruments->Instrument);

// Instruments
foreach ($sx2->PatternPool->Patterns->Pattern as $p) {
	foreach ($p->Tracks->PatternTrack as $x) {
		if ($x->Lines->Line) {
			foreach ($x->Lines->Line as $y) {
				if ($y->NoteColumns->NoteColumn) {
					foreach ($y->NoteColumns->NoteColumn as $z) {
						if ($z->Instrument) {
							list($instr) = sscanf($z->Instrument, '%x');
							  $z->Instrument = sprintf("%02X", $instr + $offset);
						}
					}
				}
			}
		}
	}
}

// VstiAutomationDevices
foreach ($sx2->Tracks->SequencerTrack as $x) {
	if ($x->FilterDevices->Devices->VstiAutomationDevice) {
		foreach ($x->FilterDevices->Devices->VstiAutomationDevice as $y) {
			list($instr) = sscanf($y->LinkedInstrument, '%x');
			$y->LinkedInstrument = sprintf("%02X", $instr + $offset);
		}
	}
}

// SampleData directory
if (is_dir($unzip2 . '/SampleData/')) {
	foreach(new DirectoryIterator($unzip2 . '/SampleData/') as $file) {

		if ($file == '.' || $file == '..') continue; // Skip these files

		// Source
		$source = $unzip2 . '/SampleData/' . $file;

		// Destination
		$dest = preg_replace('/(^\D+)(\d+)/', '$1@_REPLACE_@', $file);
		preg_match('/\d+/', $file, $matches);
		$shift = str_pad(($matches[0]  + $offset), 2, '0', STR_PAD_LEFT);
		$dest = str_replace('@_REPLACE_@', $shift, $dest);
		$dest = $unzip1 . '/SampleData/' . $dest;

		// Copy
		dircopy($source, $dest);

	}
}


// ----------------------------------------------------------------------------
// Send devices in song2 are shifted the total send tracks in song1, adjust
// the pointer offsets accordingly.
// ----------------------------------------------------------------------------

$offset = count($sx1->Tracks->SequencerSendTrack);
foreach ($sx2->Tracks->SequencerTrack as $x) {
	if ($x->FilterDevices->Devices->SendDevice) {
		foreach ($x->FilterDevices->Devices->SendDevice as $y) {
			$shift = str_pad(($y->DestSendTrack->Value + $offset), 2, '0', STR_PAD_LEFT);
			$y->DestSendTrack->Value = $shift;
		}
	}
}


// ----------------------------------------------------------------------------
// Append all the instruments, tracks, sends, patterns, and sequences from
// song2 into song1.
// ----------------------------------------------------------------------------

// Instruments
foreach ($sx2->Instruments->Instrument as $x) {
	simplexml_append($sx1->Instruments, $x);
}

// Tracks
foreach ($sx2->Tracks->SequencerTrack as $x) {
	simplexml_insert_before($sx1->Tracks, $x, $sx1->Tracks->SequencerMasterTrack);
}

// SendTracks
foreach ($sx2->Tracks->SequencerSendTrack as $x) {
	simplexml_append($sx1->Tracks, $x);
}

// Patterns
foreach ($sx2->PatternPool->Patterns->Pattern as $x) {
	simplexml_append($sx1->PatternPool->Patterns, $x);
}

// PatternSequence
foreach ($sx2->PatternSequence->PatternSequence->Pattern as $x) {
	simplexml_append($sx1->PatternSequence->PatternSequence, $x);
}


// ----------------------------------------------------------------------------
// Validate
// ----------------------------------------------------------------------------

if (file_exists($schema)) {
	$dd = new DOMDocument;
	$dd->loadXML($sx1->asXML());
	if(!$dd->schemaValidate($schema)) {
		die("Error: XML is invalid!\n");

	}
}

// ----------------------------------------------------------------------------
// Replace Song.xml
// ----------------------------------------------------------------------------

unlink($unzip1 . 'Song.xml') or die("Error: There was a problem deleting a file.\n");
file_put_contents($unzip1 . 'Song.xml', $sx1->asXML());

// Zip song
$result = ZipAllFiles($song3, $unzip1);
if($result === FALSE) {
	die("Error: There was a problem zipping the final file.\n");
}

// ----------------------------------------------------------------------------
// Remove temp directories
// ----------------------------------------------------------------------------

obliterate_directory($unzip1);
obliterate_directory($unzip2);

echo "Done...\n";

?>


#28 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 30 May 2007 - 23:59

Holy crap, thanks Taktik. It works!

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#29 Belkin

Belkin

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 302 posts
  • Location:Ukraine, Lviv
  • Interests:Music

Posted 31 May 2007 - 13:37

ok
now i can start rewrite it to c#
to taktik
if i will create lib (dll) file can you add it to renoise as new feature?
Life is too short to listen to slow music
IPB Image
IPB Image
IPB Image
IPB Image

#30 xerxes

xerxes

    Big Masta Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPip
  • 569 posts

Posted 31 May 2007 - 15:07

thank god we have such excellent people using renoise! this will be a fantastic addition to renoise, and as far as i know, not possible in any other music software.. yes? no? :)


cheers
klaus
www.xerxes-music.com

#31 Belkin

Belkin

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 302 posts
  • Location:Ukraine, Lviv
  • Interests:Music

Posted 31 May 2007 - 15:48

as i know FL have feature that you can write track by internet) with other guys)
Life is too short to listen to slow music
IPB Image
IPB Image
IPB Image
IPB Image

#32 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 31 May 2007 - 16:42

Belkin, I recieved your PM but will not be adding you to MSN/ICQ. My free timne is mine, not everyone elses. Look for me in the Renoise #irc if you need me, or post your questions in this thread. I can't help you with your C# because I run off OS X. In fact, f**** C# :) Renoise is multi-platform, I don't see your .dll making it in the final release. How would I run it on OS X?

With that said, you should go ahead and write an app. It would be cool for Windows users. The algorithm is outlined in the working code/shell script above.

Good luck!

PS: A question fo team Renoise / Bantai: Is my script tool worthy?

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#33 Guest_Bantai_*

Guest_Bantai_*
  • Guests

Posted 31 May 2007 - 17:29

Eventually yes, ofcourse. But has it been tested thoroughly enough to add it now?

Also, since this one is php only, can someone write a visual standalone version?

#34 Belkin

Belkin

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 302 posts
  • Location:Ukraine, Lviv
  • Interests:Music

Posted 31 May 2007 - 17:33

i will create dll file.
and small application for test it after this public it here.
all members who wnat can test it after this i can send dll file to ya with sources and class descriptions.

after this all bugs we can fix here)
Life is too short to listen to slow music
IPB Image
IPB Image
IPB Image
IPB Image

#35 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 31 May 2007 - 18:00

But has it been tested thoroughly enough to add it now?


Probably not. But it worked for me. But, yeah, it warrants a few weeks of wait time.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#36 taktik

taktik

    Renoise Developer

  • Admins
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 15040 posts
  • Gender:Male
  • Location:Berlin, Germany
  • Interests:füße waschen

Posted 31 May 2007 - 20:52

Probably not. But it worked for me. But, yeah, it warrants a few weeks of wait time.


The probs (missing shifts/edits) I can think of are:

- Offsets in VSTi alias indices
(RenoiseSong->Instruments->Instrument[x]->VSTiProperties->AutoAssignedTrack, when not -1)

- Offsets in VST autoassign track refs (RenoiseSong->Instruments->Instrument[x]->VSTiProperties->AliasInstrumentIndex, when not -1)

- Offsets in the MIDI CC Device (like the VST automation Device)

- The patterns support up to FF instruments only

#37 twilek

twilek

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1016 posts
  • Gender:Male

Posted 19 June 2007 - 19:48

I can't help you with your C# because I run off OS X. In fact, f**** C# :) ... How would I run it on OS X?


Ever tried Mono? With Mono you can run C# and other .NET-apps on Linux, Solaris, Mac OS X, Windows, and Unix. Even if Microsoft refuse to make their implementation work with any other platform than windows, fortunately other people care to do such an implementation. Mono rocks, and C# is indeed a pretty nice language (and that is said by a person that usually doesn't have much good to say about things that comes out of Microsoft ;)) ...

Edited by twilek, 19 June 2007 - 19:53.

tWilek ;-)
--------------------

#38 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 19 June 2007 - 23:10

Well, it's available in PHP5, now...

But yeah, no real criticisms about C# other than if it's so great, then where's the C# merge application people? ;-)

I'm not going to write an app that was easy to make in PHP using a language I don't know. The fact that it took me a few days and a review by Taktik, who was able to read/fix my code, speaks for itself. Obviously not everyone rocks the command prompt with PHP5 in their bin dir, but when you need to get things done, and you don't have a Perl developer around, PHP gets it done too.

It's all good.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#39 taktik

taktik

    Renoise Developer

  • Admins
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 15040 posts
  • Gender:Male
  • Location:Berlin, Germany
  • Interests:füße waschen

Posted 21 June 2007 - 10:13

Btw, should I solve/add the remaining missing stuff (as noted in my previous reply) or will you? Would be great to get it finished to add it to the tools download section...

#40 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 21 June 2007 - 15:46

Yeah, you are right. I have a bit more time now. Give me the weekend and I will add those fixes/safeties.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#41 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 21 June 2007 - 15:57

- The patterns support up to FF instruments only


What does this mean?

if ((count($sx1->Instruments->Instrument) + count($sx2->Instruments->Instrument)) > 255) die("Unsuported"); // ?

Or does it literally mean that if I have more than 255 instruments per pattern, it can't be done?

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#42 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 21 June 2007 - 17:10

Here's a cleaner version of the script.

* More verbose.
* Try to find the user's temp directory if set incorrectly in variables.
* Abort and clean up if resulting merge would create more than 255 instruments (needs peer review)
* Moved zip/unzip out of variables, into functions.
* Cleaned up a few other things.
* EDIT: Use double quotes in case temp dir has spaces.

EDIT: Scroll Down...

Edited by Conner_Bw, 23 June 2007 - 18:49.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#43 taktik

taktik

    Renoise Developer

  • Admins
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 15040 posts
  • Gender:Male
  • Location:Berlin, Germany
  • Interests:füße waschen

Posted 21 June 2007 - 20:18

What does this mean?

if ((count($sx1->Instruments->Instrument) + count($sx2->Instruments->Instrument)) > 255) die("Unsuported"); // ?

Or does it literally mean that if I have more than 255 instruments per pattern, it can't be done?


Yes, 0xff is the highest instrument index that you can be used in the pattern editor, so you should check this and bail out, or warn that some notes from song2 will be missing...

#44 Belkin

Belkin

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 302 posts
  • Location:Ukraine, Lviv
  • Interests:Music

Posted 22 June 2007 - 10:13

in this holidays i will have some free time and will try to rewrite it to C# dll
Life is too short to listen to slow music
IPB Image
IPB Image
IPB Image
IPB Image

#45 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 23 June 2007 - 18:48

A question for Taktic:

In my test cases:

EDIT: Scroll down...

Edited by Conner_Bw, 23 June 2007 - 22:13.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#46 taktik

taktik

    Renoise Developer

  • Admins
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 15040 posts
  • Gender:Male
  • Location:Berlin, Germany
  • Interests:füße waschen

Posted 23 June 2007 - 19:14

A question for Taktic:

In my test cases:

// VSTi AliasInstrumentIndex
foreach ($sx2->Instruments->Instrument as $x) {
	if ($x->VstiProperties->AliasInstrumentIndex >= 0) {		
			list($instr) = sscanf($x->VstiProperties->AliasInstrumentIndex, '%x');
			$x->VstiProperties->AliasInstrumentIndex = sprintf("%02X", $instr + $offset);			 
		  
	}
}

When validated against RenoiseSong4.xsd (set with $schema as a variable) fails with: Warning: DOMDocument::schemaValidate(): Element 'AliasInstrumentIndex': '0F' is not a valid value of the atomic type 'xs:int'. in /Users/dac514/Desktop/xrns_merge/xrns_merge.php on line 411
So i changed it to:

// VSTi AliasInstrumentIndex
foreach ($sx2->Instruments->Instrument as $x) {
	if ($x->VstiProperties->AliasInstrumentIndex >= 0) {			
			$shift = str_pad(($x->VstiProperties->AliasInstrumentIndex + $offset), 2, '0', STR_PAD_LEFT);
			$x->VstiProperties->AliasInstrumentIndex = $shift;			
	}
}
But then, I investigated further and the schema does not accept HEX values anywhere? I'm guessing XML doesn't handle HEX? In any case, the only places it might apply are "MidiCCDevice" and "Instruments" because they are type="xs:string" ... So without further ado, here is the FINAL script?


Uhm yeah. My fault. The only place where hex ints are used is in the patterns (for the instrument shifts in your case). So you should use simple unpadded decimal ints everywhere else...

One more thing:

You are shifting "VstiProperties->AutoAssignedTrack" by the instrument count of the first song. Should be the track count in this case.
Also this is even needed for song1 when AutoAssignedTrack is the master track (may be a rare case, but possible). We all love details, dont we ;)

#47 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 23 June 2007 - 19:45

Also this is even needed for song1 when AutoAssignedTrack is the master track (may be a rare case, but possible). We all love details, dont we ;)


Doh, OK. I will fix this.

Also, please confirm:
* MidiCCDevice expects and int?
* Padding is useless, everywhere?

Thanks.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#48 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 23 June 2007 - 20:06

Also this is even needed for song1 when AutoAssignedTrack is the master track (may be a rare case, but possible). We all love details, dont we ;)


On second thought, I don't understand this.

I understand "You are shifting "VstiProperties->AutoAssignedTrack" by the instrument count of the first song. Should be the track count in this case." which I have fixed... But how do I shift a master track if there can only be 1? As song #2's master track gets dropped in the merge, do you mean I have to not shift if it's pointing at the master track? Something along the lines of && $x->VstiProperties->AutoAssignedTrack != ($offset2 - 1) i.e.


$offset = count($sx1->Tracks->SequencerTrack);
$offset2 = count($sx2->Tracks->SequencerTrack);

foreach ($sx2->Instruments->Instrument as $x) {		
	if ($x->VstiProperties->AutoAssignedTrack >= 0 && $x->VstiProperties->AutoAssignedTrack != ($offset2 - 1)) {			
			$shift = str_pad(($x->VstiProperties->AutoAssignedTrack + $offset), 2, '0', STR_PAD_LEFT);
			$x->VstiProperties->AutoAssignedTrack = $shift;			  
	}
}


Edited by Conner_Bw, 23 June 2007 - 20:44.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#49 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 23 June 2007 - 20:40

Ok... I'm lost.

THE XML generated when I assign MASTER to Assign to Track on a VSTi is:

		<AutoAssignTrack>false</AutoAssignTrack>
		<AutoAssignedTrack>-1</AutoAssignedTrack>

So i don't have to check for anything at all...

foreach ($sx2->Instruments->Instrument as $x) {		
	if ($x->VstiProperties->AutoAssignedTrack >= 0) {			
			$shift = str_pad(($x->VstiProperties->AutoAssignedTrack + $offset), 2, '0', STR_PAD_LEFT);
			$x->VstiProperties->AutoAssignedTrack = $shift;			  
	}
}

Should cover all cases?

Edited by Conner_Bw, 23 June 2007 - 20:45.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »


#50 Conner_Bw

Conner_Bw

    Probably More God or Borg Than Human Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 7108 posts
  • Gender:Male
  • Location:Montreal, Quebec, Canada

Posted 23 June 2007 - 22:14

Upon further review... MidiCCDevice->...->LinkedInstrument should probably remain HEX. Please find attached what I believe to be the final version of the script. All superfluous padding has been removed.

:dribble: :drummer: :guitar: :huh: :lol: :o :panic: :(

EDIT: Scroll down...

Edited by Conner_Bw, 23 June 2007 - 22:51.

cpu Lenovo X220, Intel i7-2640M @ 2.80GHz ×4 os Windows 10 / Ubuntu 16.04 LTS
My Homepage » : My Renoise Tools » : Normalize Your Sig » : One million clicks! »