SuperDirt
SuperDirt copied to clipboard
Inconsistent sorting of files
It seems that given a folder with files kicksnare.wav
and kick.wav
, linux based systems sort the former first, and others sort the latter first. Probably because other systems ignore the extension when sorting. This means d1 $ sound "gretsch:13"
gives a kick on some systems, and a kick-snare on others.
I made a quick script for finding problem folders:
#!/bin/bash
for d in */ ; do
diff <(ls $d|tr ' ' '_'|xargs basename -s.wav -a|sort) <(ls $d|tr ' ' '_'|sort|xargs basename -s.wav -a) >/dev/null
if [ $? -ne 0 ]; then
echo "$d has a problem.."
fi
done
There's quite a few:
auto/ birds/ east/ gretsch/ h/ if/ jungbass/ mash2/ mute/ peri/ popkick/ print/ speakspell/ speechless/ toys/ trump/ ul/
Not sure of the best approach to a fix - by renaming the files to make sorting unambiguous, by fixing superdirt to sort one way or the other, or maybe this is a bug in supercollider.
I've disambiguated the filenames for now with this
#!/usr/bin/perl -w
use strict;
my $dirname = shift @ARGV;
opendir(DIR, $dirname) or die "Could not open $dirname\n";
my @files;
while (my $filename = readdir(DIR)) {
if ($filename =~ /(.*?)\.wav$/i) {
push(@files,[$1,$filename]);
}
}
@files = sort {$a->[0] cmp $b->[0]} @files;
my $n = 0;
foreach my $file (@files) {
my $new = sprintf("%03d_$file->[1]", $n++);
system("git", "mv", "$dirname/$file->[1]","$dirname/$new");
print("rename($dirname/$file->[1], $dirname/$new)\n");
}
closedir(DIR);
Are you sure this is an issue for SuperCollider sort order and not just shell sort
? I think sort
output can depend on the shell and environment variable settings, none of which likely matter to SuperCollider
I think it would be good for superdirt behaviour to be consistent across platforms, so I think it (or supercollider) needs to do its own sort. I'd vote on one that sorts based on the basename (without extension), as to me that seems least surprising.
It'll be very easy to fix this. You just need to sort the paths after line 172:
https://github.com/musikinformatik/SuperDirt/blob/dd378ea88b014b3e20dbe4bf77138c0eadbe06ce/classes/DirtSoundLibrary.sc#L172-L173
The easiest is just "sort", maybe out of politeness:
files = files.copy.sort
because sort is an in place operation.
You may want to have a better sorting function, recently @adcxyz has posted one, this could be integrated. But maybe the simple "sort" is fine?
@telephon is referring to 'naturalLess' for natural-sorting Strings, see code and examples here: https://github.com/supercollider-quarks/adclib/blob/master/Classes/extNatSort.sc https://github.com/supercollider-quarks/adclib/blob/master/Classes/TestNatSort.scd
I think the sort
method can be enough.
Looking at the supercollider source, it sorts by character ASCII value:
sort
https://github.com/supercollider/supercollider/blob/cc56c994fa205e3df53db9b6615753b55cc259fa/SCClassLibrary/Common/Collections/SequenceableCollection.sc#L1251
<
operator on Char
class
https://github.com/supercollider/supercollider/blob/cc56c994fa205e3df53db9b6615753b55cc259fa/SCClassLibrary/Common/Core/Char.sc#L99
Yes, you can sort strings like that. The chenge should be made in loadSoundFileFolder
. This will be a breaking change, so we may have to be careful.
files = pathMatch(folderPath.standardizePath +/+ "*"); // dependent on operating system
files.sort;
Yep. It will be a breaking change anyway, but with some well defined rules, so easier for the clients to replicate. A "natural sorting" could be more tricky
Once we are agreed upon what the sorting should be, I can add it easily. I'm just not sure what is needed.
Can we agree on the particular way to sort the samples? It would be great to have the same code produce the same output when working with different OS'.
I'd propose to just use the sclang implementation of string sorting.
please test if it solves the issue for you …
String sorting would work for me too, as in #214