acheney
6 months ago
4 changed files with 955 additions and 2 deletions
@ -1,2 +1,15 @@ |
|||||||
# scl_to_sunvox_converters |
# abstract |
||||||
|
|
||||||
|
here are two files for converting `.scl` files to sunvox's own pitch format |
||||||
|
|
||||||
|
they are: |
||||||
|
|
||||||
|
- `scl_to_curve3.pixi`: converts `.scl` files to a `.curve16bit` file for the multisynth's curve3. you can also specify a scale to map to 12 notes; details are in the file |
||||||
|
- `scl_to_set_pitch.pixi`: converts `.scl` files to a sunvox project with all of the notes in the tuning laid out as SP (set pitch) commands |
||||||
|
|
||||||
|
to use these, download pixilang and run the `.pixi` file of your choosing. all of the information in the log will be displayed on the screen |
||||||
|
|
||||||
|
# credits |
||||||
|
|
||||||
|
the program was written by me, except for the `show_log()` function, which was originally written by nightradio and modified by me |
||||||
|
|
||||||
|
@ -0,0 +1,526 @@ |
|||||||
|
// .scl to sunvox curve3 converter |
||||||
|
// by acheney |
||||||
|
// under mit license |
||||||
|
|
||||||
|
// NOTE: BE SURE THERE ARE NO DUPLICATE LINE ENDINGS IN YOUR .SCL FILE, OR ELSE THE SCRIPT WILL FAIL! |
||||||
|
// .scl files generated using sevish's scale workshop should work fine, as well as .scl files saved locally on your system |
||||||
|
// but if you download an .scl file from anywhere else, be sure to convert the line endings to those of your os |
||||||
|
// on linux/osx you can use dos2unix, and on windows unix2dos, or for both, any text editor that lets you convert line endings |
||||||
|
|
||||||
|
// - BEGIN CONFIG - |
||||||
|
|
||||||
|
// the frequency of the tuning center in hertz |
||||||
|
tuning_center_freq = 440 |
||||||
|
|
||||||
|
// the midi note to use as the tuning center. 57 = A4 |
||||||
|
tuning_center_midi = 57 |
||||||
|
|
||||||
|
// enables mapping the tuning to 12 notes |
||||||
|
// the notes will be mapped according to brensenham's line algorithm |
||||||
|
map_to_12_notes = 0 |
||||||
|
|
||||||
|
// if map_to_12_notes is enabled, change the below declaration to your desired mapping |
||||||
|
// the indices of the tuning start at 0 |
||||||
|
// the below example is a ten-note tuning mapped to 12 notes |
||||||
|
|
||||||
|
map_scale = new( 10, 1, INT16 ) |
||||||
|
|
||||||
|
map_scale[ 0 ] = 0 |
||||||
|
map_scale[ 1 ] = 1 |
||||||
|
map_scale[ 2 ] = 2 |
||||||
|
map_scale[ 3 ] = 3 |
||||||
|
map_scale[ 4 ] = 4 |
||||||
|
map_scale[ 5 ] = 5 |
||||||
|
map_scale[ 6 ] = 6 |
||||||
|
map_scale[ 7 ] = 7 |
||||||
|
map_scale[ 8 ] = 8 |
||||||
|
map_scale[ 9 ] = 9 |
||||||
|
|
||||||
|
// - END CONFIG - |
||||||
|
|
||||||
|
scl_filename = file_dialog( "load .scl file", "scl", "file.scl" ) |
||||||
|
|
||||||
|
scl_name = "" |
||||||
|
scl_size = 0 |
||||||
|
scl_list = new( 1024, 1, INT8 ) |
||||||
|
scl_pitches = new( 128, 1, INT16 ) |
||||||
|
|
||||||
|
clean( scl_list, 0 ) |
||||||
|
clean( scl_pitches, 0 ) |
||||||
|
|
||||||
|
scl_read( scl_filename ) |
||||||
|
|
||||||
|
logf( "name: %s\n", scl_name ) |
||||||
|
logf( "size: %d\n", scl_size ) |
||||||
|
|
||||||
|
resize( scl_list, scl_size ) |
||||||
|
|
||||||
|
if (scl_size > 0 ) { |
||||||
|
|
||||||
|
scl_write( ) |
||||||
|
|
||||||
|
if map_to_12_notes |
||||||
|
{ |
||||||
|
scl_pitches = scl_map( map_scale, scl_pitches, scl_size ) |
||||||
|
|
||||||
|
if scl_pitches != -1 |
||||||
|
{ |
||||||
|
|
||||||
|
scl_save( scl_name, scl_pitches ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
scl_save( scl_name, scl_pitches ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
logf( "\n" ) |
||||||
|
|
||||||
|
show_log() |
||||||
|
|
||||||
|
fn scl_read( $scl_filename ) { |
||||||
|
|
||||||
|
$temp_string = new( 1024, 1, INT8 ) |
||||||
|
$length = 0 |
||||||
|
$metadata_counter = 0 |
||||||
|
$list_counter = 0 |
||||||
|
$is_comment = 0 |
||||||
|
|
||||||
|
logf( "file to load: %s\n", $scl_filename ) |
||||||
|
$scl_file = fopen( $scl_filename, "r" ) |
||||||
|
|
||||||
|
if $scl_file == 0 { ret( -1 ) } |
||||||
|
|
||||||
|
while 1 { |
||||||
|
|
||||||
|
$length = fgets( $temp_string, 2048, $scl_file ) |
||||||
|
|
||||||
|
if ( $length == -1 ) { |
||||||
|
|
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $length >= 0 ) { |
||||||
|
|
||||||
|
// logf( "read string: %s\n", $temp_string ) |
||||||
|
|
||||||
|
if ( $temp_string[ 0 ] == '!' ) { |
||||||
|
|
||||||
|
$is_comment = 1 |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
$is_comment = 0 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $is_comment == 0 ) { |
||||||
|
|
||||||
|
if ( $metadata_counter >= 2 ) { |
||||||
|
|
||||||
|
scl_list[ $list_counter ] = strip_character( $temp_string, ' ' ) |
||||||
|
$list_counter = $list_counter + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $metadata_counter == 1 ) { |
||||||
|
|
||||||
|
$metadata_counter = 2 |
||||||
|
|
||||||
|
if ($length == 0) { |
||||||
|
|
||||||
|
logf("ERROR: no size specified\n") |
||||||
|
|
||||||
|
breakall |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// logf( "number conversion: %d\n", str_to_num( strip_character( $temp_string, ' ' ) ) ) |
||||||
|
scl_size = str_to_num( strip_character( $temp_string, ' ' ) ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $metadata_counter == 0 ) { |
||||||
|
|
||||||
|
$metadata_counter = 1 |
||||||
|
|
||||||
|
if ($length == 0) { |
||||||
|
|
||||||
|
logf("WARNING: no name found. defaulting to filename...\n") |
||||||
|
|
||||||
|
strcat( scl_name, basename( $scl_filename, 0 ) ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
strcat( scl_name, $temp_string ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// logf( "comment found, skipping...\n" ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
remove( $temp_string ) |
||||||
|
fclose( $scl_file ) |
||||||
|
} |
||||||
|
|
||||||
|
fn strip_character( $input, $c ) { |
||||||
|
|
||||||
|
$non_char_count = 0 |
||||||
|
$dest = clone( $input ) |
||||||
|
|
||||||
|
$i = 0 while $i < get_xsize( $input ) + 1 { |
||||||
|
|
||||||
|
if ( $input[ $i ] != $c ) { |
||||||
|
|
||||||
|
$dest[ $non_char_count ] = $input[ $i ] |
||||||
|
$non_char_count = $non_char_count + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
$i = $i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $dest ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn scl_write( ) { |
||||||
|
|
||||||
|
scl_multipliers = new( scl_size, 1, FLOAT ) |
||||||
|
current_midi = 0 |
||||||
|
multiplier_power = 1 |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( scl_list ) { |
||||||
|
|
||||||
|
scl_multiplier = 0 |
||||||
|
current_midi = 0 |
||||||
|
|
||||||
|
if ( strstr( scl_list[ i ], "." ) != -1 ) { |
||||||
|
|
||||||
|
scl_multiplier = pow( 2, ( ( str_to_num( scl_list[ i ] ) / 100 ) / 12 ) ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
numerator = new( 256, 1, INT8 ) |
||||||
|
clean( numerator, 0 ) |
||||||
|
|
||||||
|
denominator = new( 256, 1, INT8 ) |
||||||
|
clean ( denominator, 0 ) |
||||||
|
|
||||||
|
slash_offset = 0 |
||||||
|
no_denominator = 0 |
||||||
|
|
||||||
|
j = 0 while 1 { |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j ] == '/' || scl_list[ i ][ j ] == '\\' ) { |
||||||
|
|
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j ] == ' ' || scl_list[ i ][ j ] == 0 ) { |
||||||
|
|
||||||
|
no_denominator = 1 |
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
numerator[ j ] = scl_list[ i ][ j ] |
||||||
|
|
||||||
|
j = j + 1 |
||||||
|
|
||||||
|
slash_offset = slash_offset + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( no_denominator == 0 ) { |
||||||
|
|
||||||
|
j = 0 while 1 { |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j + slash_offset + 1 ] == 0 || scl_list[ i ][ j + slash_offset + 1 ] == ' ' ) { |
||||||
|
|
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
denominator[ j ] = scl_list[ i ][ j + slash_offset + 1 ] |
||||||
|
|
||||||
|
j = j + 1 |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
denominator[ 0 ] = '1' |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
scl_multiplier = str_to_num( numerator ) / str_to_num( denominator ) |
||||||
|
} |
||||||
|
|
||||||
|
scl_multipliers[ i ] = scl_multiplier |
||||||
|
|
||||||
|
// logf( "multiplier written to %d: %f\n", i, scl_multipliers[ i ] ) |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( scl_multipliers ) { |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
} |
||||||
|
|
||||||
|
i = 0 while i < 128 { |
||||||
|
|
||||||
|
multiplier_power = floor( ( i - tuning_center_midi ) / scl_size ) |
||||||
|
// logf( "multiplier power: %d\n", multiplier_power ) |
||||||
|
|
||||||
|
center_offset = pow( scl_multipliers[ scl_size - 1 ], multiplier_power ) |
||||||
|
// logf( "center offset: %d\n", center_offset ) |
||||||
|
|
||||||
|
if ( i < tuning_center_midi ) { |
||||||
|
scl_pitches[ i ] = freq_to_pitch( tuning_center_freq * scl_multipliers[ ( ( ( i - tuning_center_midi ) % scl_size ) - 1 ) + scl_size ] * center_offset ) |
||||||
|
} |
||||||
|
if ( i > tuning_center_midi ) { |
||||||
|
scl_pitches[ i ] = freq_to_pitch( tuning_center_freq * scl_multipliers[ ( i - tuning_center_midi ) % ( scl_size ) - 1 ] * center_offset ) |
||||||
|
} |
||||||
|
if ( ( tuning_center_midi - i ) % scl_size == 0 ) { |
||||||
|
scl_pitches[ i ] = freq_to_pitch( tuning_center_freq * center_offset ) |
||||||
|
} |
||||||
|
|
||||||
|
// logf( "pitch written to %d: %d\n", i, scl_pitches[ i ] ) |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn freq_to_pitch( $freq ) { |
||||||
|
|
||||||
|
ret( log2( $freq / 16.333984375 ) * 3072 + 16384 ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn scl_save( $name, $pitches ) |
||||||
|
{ |
||||||
|
|
||||||
|
$name = sanitize( $name ) |
||||||
|
// logf( "sanitized filename: %s\n", $name ) |
||||||
|
|
||||||
|
strcat( $name, ".curve16bit" ) |
||||||
|
|
||||||
|
if save( $pitches, $name, FORMAT_RAW ) == 0 { logf( "file saved!\n" ) } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn scl_map( $scale, $tuning, $tuning_length ) |
||||||
|
{ |
||||||
|
|
||||||
|
$tuning_dest = clone( $tuning ) |
||||||
|
|
||||||
|
$scale_length = get_size( $scale ) |
||||||
|
|
||||||
|
if $scale_length > $tuning_length |
||||||
|
{ |
||||||
|
|
||||||
|
logf( "ERROR: scale length is greater than tuning size\n" ) |
||||||
|
|
||||||
|
ret( -1 ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if $scale_length > 12 |
||||||
|
{ |
||||||
|
|
||||||
|
logf( "ERROR: scale length is greater than 12\n" ) |
||||||
|
|
||||||
|
ret( -1 ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if $scale[ $scale_length - 1 ] > ( $tuning_length - 1 ) |
||||||
|
{ |
||||||
|
|
||||||
|
logf( "ERROR: scale degrees are greater than tuning size\n" ) |
||||||
|
|
||||||
|
ret( -1 ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
$i = 0 while $i < 128 { |
||||||
|
|
||||||
|
// logf( "i: %d\n", $i ) |
||||||
|
|
||||||
|
$mod_keyboard_index = ( ( $i + 12 ) - ( ( tuning_center_midi ) % 12 ) ) % 12 |
||||||
|
// logf( "mod keyboard index: %f\n", $mod_keyboard_index ) |
||||||
|
|
||||||
|
$mod_period = floor( ( $i - ( tuning_center_midi ) ) / 12 ) |
||||||
|
// logf( "mod period: %f\n", $mod_period ) |
||||||
|
|
||||||
|
$mod_tuning_index = brensenham( 0, 0, 11, $scale_length - 1 , $mod_keyboard_index ) |
||||||
|
// logf( "mod tuning index: %f\n", $mod_tuning_index ) |
||||||
|
|
||||||
|
$mod_scale_index = $scale[ $mod_tuning_index ] |
||||||
|
// logf( "mod scale index: %f\n", $mod_scale_index ) |
||||||
|
|
||||||
|
$mod_tuning_lookup = $mod_scale_index + ( ( $tuning_length ) * $mod_period ) + tuning_center_midi |
||||||
|
// logf( "mod tuning lookup: %f\n", $mod_tuning_lookup ) |
||||||
|
|
||||||
|
$tuning_dest[ $i ] = $tuning[ $mod_tuning_lookup ] |
||||||
|
|
||||||
|
$i = $i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $tuning_dest ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn sanitize( $input ) |
||||||
|
{ |
||||||
|
|
||||||
|
$output = clone( $input ) |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( $input ) { |
||||||
|
|
||||||
|
|
||||||
|
if $input[ i ] == '/' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\\' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\'' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\"' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\ ' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == ':' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == ',' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '.' { $output[ i ] = '_' } |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $output ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn strrchr( $s, $c ) |
||||||
|
{ |
||||||
|
|
||||||
|
$i = 0 |
||||||
|
$k = 0 |
||||||
|
|
||||||
|
for( $i = strlen( $s ); $i >= 0; $i - 1 ) |
||||||
|
{ |
||||||
|
|
||||||
|
if $s[ $i ] == $c { |
||||||
|
|
||||||
|
$k = 1 |
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if $k { ret( $i ) } else { ret( -1 ) } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn basename( $p, $x ) |
||||||
|
{ |
||||||
|
|
||||||
|
$n = "" |
||||||
|
strcat( $n, 0, $p, strrchr( $p, '/' ) + 1 ) |
||||||
|
|
||||||
|
if $x |
||||||
|
{ |
||||||
|
|
||||||
|
ret( $n ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
$nnxl = strrchr( $n, '.' ) |
||||||
|
$nnx = new( $nnxl, 1, INT8 ) |
||||||
|
|
||||||
|
$i = 0 while $i < get_size( $nnx ) |
||||||
|
{ |
||||||
|
|
||||||
|
$nnx[ $i ] = $n[ $i ] |
||||||
|
|
||||||
|
$i = $i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $nnx ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn brensenham( $x0, $y0, $x1, $y1, $xi ) |
||||||
|
{ |
||||||
|
|
||||||
|
$dx = $x1 - $x0 |
||||||
|
$dy = $y1 - $y0 |
||||||
|
|
||||||
|
$d = 2 * $dy - $dx |
||||||
|
|
||||||
|
$y = $y0 |
||||||
|
|
||||||
|
$x = $x0 while $x < $xi { |
||||||
|
|
||||||
|
if $d > 0 |
||||||
|
{ |
||||||
|
|
||||||
|
$y = $y + 1 |
||||||
|
$d = $d - 2 * $dx |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
$d = $d + 2 * $dy |
||||||
|
|
||||||
|
$x = $x + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $y ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn show_log() |
||||||
|
{ |
||||||
|
|
||||||
|
$l = get_system_log() |
||||||
|
clear() |
||||||
|
print( $l, 0, 0, WHITE, CENTER | CENTER ) |
||||||
|
frame() |
||||||
|
remove( $l ) |
||||||
|
|
||||||
|
while 1 |
||||||
|
{ |
||||||
|
while( get_event() ) { if EVT[ EVT_TYPE ] == EVT_QUIT { halt } } |
||||||
|
frame() |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,414 @@ |
|||||||
|
// .scl to sunvox set pitch (sp) converter |
||||||
|
// by acheney |
||||||
|
// under mit license |
||||||
|
|
||||||
|
// NOTE: BE SURE THERE ARE NO DUPLICATE LINE ENDINGS IN YOUR .SCL FILE, OR ELSE THE SCRIPT WILL FAIL! |
||||||
|
// .scl files generated using sevish's scale workshop should work fine, as well as .scl files saved locally on your system |
||||||
|
// but if you download an .scl file from anywhere else, be sure to convert the line endings to those of your os |
||||||
|
// on linux/osx you can use dos2unix, and on windows unix2dos, or for both, any text editor that lets you convert line endings |
||||||
|
|
||||||
|
// - BEGIN CONFIG - |
||||||
|
|
||||||
|
// the frequency of the tuning center in hertz |
||||||
|
tuning_center_freq = 440 |
||||||
|
|
||||||
|
// the midi note to use as the tuning center. 57 = A4 |
||||||
|
tuning_center_midi = 57 |
||||||
|
|
||||||
|
// - END CONFIG - |
||||||
|
|
||||||
|
sv = sv_new() |
||||||
|
|
||||||
|
scl_filename = file_dialog( "load .scl file", "scl", "file.scl" ) |
||||||
|
|
||||||
|
scl_name = "" |
||||||
|
scl_size = 0 |
||||||
|
scl_list = new( 1024, 1, INT8 ) |
||||||
|
scl_pitches = new( 120, 1, INT16 ) |
||||||
|
|
||||||
|
clean( scl_list, 0 ) |
||||||
|
clean( scl_pitches, 0 ) |
||||||
|
|
||||||
|
scl_read( scl_filename ) |
||||||
|
|
||||||
|
logf( "name: %s\n", scl_name ) |
||||||
|
logf( "size: %d\n", scl_size ) |
||||||
|
|
||||||
|
resize( scl_list, scl_size ) |
||||||
|
|
||||||
|
if (scl_size > 0 ) { |
||||||
|
|
||||||
|
scl_write( ) |
||||||
|
|
||||||
|
sv_set_name( sv, scl_name ) |
||||||
|
|
||||||
|
sv_lock( sv ) |
||||||
|
|
||||||
|
sv_new_module( sv, "Analog generator", "Preview", 256, 512, 0 ) |
||||||
|
sv_connect_module( sv, 1, 0 ) |
||||||
|
|
||||||
|
pat = sv_new_pattern( sv, -1, 0, 0, 1, 120, 0, scl_name ) |
||||||
|
|
||||||
|
sv_unlock( sv ) |
||||||
|
|
||||||
|
i = 0 while i < 120 |
||||||
|
{ |
||||||
|
sv_lock( sv ) |
||||||
|
sv_set_pattern_event( sv, pat, 0, i, NOTECMD_SET_PITCH, 00, 02, 0000, scl_pitches[ i ] ) |
||||||
|
sv_unlock( sv ) |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
} |
||||||
|
|
||||||
|
scl_name = sanitize( scl_name ) |
||||||
|
// logf( "sanitized filename: %s\n", scl_name ) |
||||||
|
|
||||||
|
strcat( scl_name, ".sunvox" ) |
||||||
|
|
||||||
|
if sv_save( sv, scl_name ) == 0 { logf( "file saved!\n" ) } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
sv_remove( sv ) |
||||||
|
|
||||||
|
logf( "\n" ) |
||||||
|
|
||||||
|
show_log() |
||||||
|
|
||||||
|
fn scl_read( $scl_filename ) { |
||||||
|
|
||||||
|
$temp_string = new( 1024, 1, INT8 ) |
||||||
|
$length = 0 |
||||||
|
$metadata_counter = 0 |
||||||
|
$list_counter = 0 |
||||||
|
$is_comment = 0 |
||||||
|
|
||||||
|
logf( "file to load: %s\n", $scl_filename ) |
||||||
|
$scl_file = fopen( $scl_filename, "r" ) |
||||||
|
|
||||||
|
if $scl_file == 0 { ret( -1 ) } |
||||||
|
|
||||||
|
while 1 { |
||||||
|
|
||||||
|
$length = fgets( $temp_string, 2048, $scl_file ) |
||||||
|
|
||||||
|
if ( $length == -1 ) { |
||||||
|
|
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $length >= 0 ) { |
||||||
|
|
||||||
|
// logf( "read string: %s\n", $temp_string ) |
||||||
|
|
||||||
|
if ( $temp_string[ 0 ] == '!' ) { |
||||||
|
|
||||||
|
$is_comment = 1 |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
$is_comment = 0 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $is_comment == 0 ) { |
||||||
|
|
||||||
|
if ( $metadata_counter >= 2 ) { |
||||||
|
|
||||||
|
scl_list[ $list_counter ] = strip_character( $temp_string, ' ' ) |
||||||
|
$list_counter = $list_counter + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $metadata_counter == 1 ) { |
||||||
|
|
||||||
|
$metadata_counter = 2 |
||||||
|
|
||||||
|
if ($length == 0) { |
||||||
|
|
||||||
|
logf("ERROR: no size specified\n") |
||||||
|
|
||||||
|
breakall |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// logf( "number conversion: %d\n", str_to_num( strip_character( $temp_string, ' ' ) ) ) |
||||||
|
scl_size = str_to_num( strip_character( $temp_string, ' ' ) ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( $metadata_counter == 0 ) { |
||||||
|
|
||||||
|
$metadata_counter = 1 |
||||||
|
|
||||||
|
if ($length == 0) { |
||||||
|
|
||||||
|
logf("WARNING: no name found. defaulting to filename...\n") |
||||||
|
|
||||||
|
strcat( scl_name, basename( $scl_filename, 0 ) ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
strcat( scl_name, $temp_string ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// logf( "comment found, skipping...\n" ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
remove( $temp_string ) |
||||||
|
fclose( $scl_file ) |
||||||
|
} |
||||||
|
|
||||||
|
fn strip_character( $input, $c ) { |
||||||
|
|
||||||
|
$non_char_count = 0 |
||||||
|
$dest = clone( $input ) |
||||||
|
|
||||||
|
$i = 0 while $i < get_xsize( $input ) + 1 { |
||||||
|
|
||||||
|
if ( $input[ $i ] != $c ) { |
||||||
|
|
||||||
|
$dest[ $non_char_count ] = $input[ $i ] |
||||||
|
$non_char_count = $non_char_count + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
$i = $i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $dest ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn scl_write( ) { |
||||||
|
|
||||||
|
scl_multipliers = new( scl_size, 1, FLOAT ) |
||||||
|
current_midi = 0 |
||||||
|
multiplier_power = 1 |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( scl_list ) { |
||||||
|
|
||||||
|
scl_multiplier = 0 |
||||||
|
current_midi = 0 |
||||||
|
|
||||||
|
if ( strstr( scl_list[ i ], "." ) != -1 ) { |
||||||
|
|
||||||
|
scl_multiplier = pow( 2, ( ( str_to_num( scl_list[ i ] ) / 100 ) / 12 ) ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
numerator = new( 256, 1, INT8 ) |
||||||
|
clean( numerator, 0 ) |
||||||
|
|
||||||
|
denominator = new( 256, 1, INT8 ) |
||||||
|
clean ( denominator, 0 ) |
||||||
|
|
||||||
|
slash_offset = 0 |
||||||
|
no_denominator = 0 |
||||||
|
|
||||||
|
j = 0 while 1 { |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j ] == '/' || scl_list[ i ][ j ] == '\\' ) { |
||||||
|
|
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j ] == ' ' || scl_list[ i ][ j ] == 0 ) { |
||||||
|
|
||||||
|
no_denominator = 1 |
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
numerator[ j ] = scl_list[ i ][ j ] |
||||||
|
|
||||||
|
j = j + 1 |
||||||
|
|
||||||
|
slash_offset = slash_offset + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( no_denominator == 0 ) { |
||||||
|
|
||||||
|
j = 0 while 1 { |
||||||
|
|
||||||
|
if ( scl_list[ i ][ j + slash_offset + 1 ] == 0 || scl_list[ i ][ j + slash_offset + 1 ] == ' ' ) { |
||||||
|
|
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
denominator[ j ] = scl_list[ i ][ j + slash_offset + 1 ] |
||||||
|
|
||||||
|
j = j + 1 |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
denominator[ 0 ] = '1' |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
scl_multiplier = str_to_num( numerator ) / str_to_num( denominator ) |
||||||
|
} |
||||||
|
|
||||||
|
scl_multipliers[ i ] = scl_multiplier |
||||||
|
|
||||||
|
// logf( "multiplier written to %d: %f\n", i, scl_multipliers[ i ] ) |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( scl_multipliers ) { |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
} |
||||||
|
|
||||||
|
i = 0 while i < 120 { |
||||||
|
|
||||||
|
multiplier_power = floor( ( i - tuning_center_midi ) / scl_size ) |
||||||
|
// logf( "multiplier power: %d\n", multiplier_power ) |
||||||
|
|
||||||
|
center_offset = pow( scl_multipliers[ scl_size - 1 ], multiplier_power ) |
||||||
|
// logf( "center offset: %d\n", center_offset ) |
||||||
|
|
||||||
|
if ( i < tuning_center_midi ) { |
||||||
|
scl_pitches[ i ] = freq_to_sp( tuning_center_freq * scl_multipliers[ ( ( ( i - tuning_center_midi ) % scl_size ) - 1 ) + scl_size ] * center_offset ) |
||||||
|
} |
||||||
|
if ( i > tuning_center_midi ) { |
||||||
|
scl_pitches[ i ] = freq_to_sp( tuning_center_freq * scl_multipliers[ ( i - tuning_center_midi ) % ( scl_size ) - 1 ] * center_offset ) |
||||||
|
} |
||||||
|
if ( ( tuning_center_midi - i ) % scl_size == 0 ) { |
||||||
|
scl_pitches[ i ] = freq_to_sp( tuning_center_freq * center_offset ) |
||||||
|
} |
||||||
|
|
||||||
|
// logf( "pitch written to %d: %d\n", i, scl_pitches[ i ] ) |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn freq_to_sp( $freq ) { |
||||||
|
|
||||||
|
ret( 30720 - log2( $freq / 16.3339 ) * 3072 ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn sanitize( $input ) |
||||||
|
{ |
||||||
|
|
||||||
|
$output = clone( $input ) |
||||||
|
|
||||||
|
i = 0 while i < get_xsize( $input ) { |
||||||
|
|
||||||
|
|
||||||
|
if $input[ i ] == '/' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\\' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\'' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\"' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '\ ' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == ':' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == ',' { $output[ i ] = '_' } |
||||||
|
if $input[ i ] == '.' { $output[ i ] = '_' } |
||||||
|
|
||||||
|
i = i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $output ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn strrchr( $s, $c ) |
||||||
|
{ |
||||||
|
|
||||||
|
$i = 0 |
||||||
|
$k = 0 |
||||||
|
|
||||||
|
for( $i = strlen( $s ); $i >= 0; $i - 1 ) |
||||||
|
{ |
||||||
|
|
||||||
|
if $s[ $i ] == $c { |
||||||
|
|
||||||
|
$k = 1 |
||||||
|
break |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if $k { ret( $i ) } else { ret( -1 ) } |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn basename( $p, $x ) |
||||||
|
{ |
||||||
|
|
||||||
|
$n = "" |
||||||
|
strcat( $n, 0, $p, strrchr( $p, '/' ) + 1 ) |
||||||
|
|
||||||
|
if $x |
||||||
|
{ |
||||||
|
|
||||||
|
ret( $n ) |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
$nnxl = strrchr( $n, '.' ) |
||||||
|
$nnx = new( $nnxl, 1, INT8 ) |
||||||
|
|
||||||
|
$i = 0 while $i < get_size( $nnx ) |
||||||
|
{ |
||||||
|
|
||||||
|
$nnx[ $i ] = $n[ $i ] |
||||||
|
|
||||||
|
$i = $i + 1 |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
ret( $nnx ) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fn show_log() |
||||||
|
{ |
||||||
|
|
||||||
|
$l = get_system_log() |
||||||
|
clear() |
||||||
|
print( $l, 0, 0, WHITE, CENTER | CENTER ) |
||||||
|
frame() |
||||||
|
remove( $l ) |
||||||
|
|
||||||
|
while 1 |
||||||
|
{ |
||||||
|
while( get_event() ) { if EVT[ EVT_TYPE ] == EVT_QUIT { halt } } |
||||||
|
frame() |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue