Skip to content

Commit

Permalink
update + audio warp/stretch
Browse files Browse the repository at this point in the history
  • Loading branch information
SatyrDiamond committed Jun 10, 2023
1 parent 76bc28d commit 9d2397b
Show file tree
Hide file tree
Showing 156 changed files with 541 additions and 329 deletions.
9 changes: 7 additions & 2 deletions DawVert.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@
if out_type != 'debug':
CVPJ_j = song_compat.makecompat(CVPJ_j, in_type, in_dawcapabilities, out_dawcapabilities)

if in_type in ['r', 'm']: CVPJ_j = song_compat.makecompat_audiostretch(CVPJ_j, in_type, in_dawcapabilities, out_dawcapabilities)

CVPJ_j = song_compat.makecompat_any(CVPJ_j, in_type, in_dawcapabilities, out_dawcapabilities)

if in_type == 'ri' and out_type == 'mi': CVPJ_j = song_convert.ri2mi(CVPJ_j)
if in_type == 'ri' and out_type == 'r': CVPJ_j = song_convert.ri2r(CVPJ_j)

Expand All @@ -269,11 +273,12 @@
CVPJ_j = song_convert.mi2m(CVPJ_j, extra_json)
CVPJ_j = song_convert.m2r(CVPJ_j)


if out_type != 'debug':
CVPJ_j = song_compat.makecompat(CVPJ_j, out_type, in_dawcapabilities, out_dawcapabilities)

CVPJ_j = song_compat.makecompat_any(CVPJ_j, out_type, in_dawcapabilities, out_dawcapabilities)
if out_type in ['r', 'm']: CVPJ_j = song_compat.makecompat_audiostretch(CVPJ_j, out_type, in_dawcapabilities, out_dawcapabilities)

#CVPJ_j = song_compat.makecompat_any(CVPJ_j, out_type, in_dawcapabilities, out_dawcapabilities)

# ------------------------------------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------------------------------------
Expand Down
Empty file modified LICENSE
100755 → 100644
Empty file.
Empty file modified README.md
100755 → 100644
Empty file.
Empty file modified config_vst.py
100755 → 100644
Empty file.
Empty file modified config_vst_windows.py
100755 → 100644
Empty file.
Empty file modified data_idvals/adlib_rol_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/beepbox_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/boscaceoil_drumkit_midi.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/boscaceoil_drumkit_simple.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/boscaceoil_drumkit_sion.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/boscaceoil_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/caustic_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/mariopaint_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/midi_ctrl.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/midi_drumkit.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/midi_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/midi_inst_drums.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/midi_inst_group.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/names_gmmidi.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/names_gmmidi_drums.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/noteblockstudio_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/notessimo_v2_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/notessimo_v3_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/notessimo_v3_inst_group.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_drumkit.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_drumkit_2013.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_drumkit_808.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_drumkit_909.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_drumkit_retro.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/onlineseq_inst.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/orgyana_inst_drums.csv
100755 → 100644
Empty file.
Empty file modified data_idvals/soundclub2_inst.csv
100755 → 100644
Empty file.
Empty file modified dawvert_cmd.py
100755 → 100644
Empty file.
Empty file modified docs/dawvert.svg
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified docs/experiments.md
100755 → 100644
Empty file.
Empty file modified docs/input_plugins.md
100755 → 100644
Empty file.
Empty file modified docs/vsts.md
100755 → 100644
Empty file.
Empty file modified experiments_plugin_input/__init__.py
100755 → 100644
Empty file.
Empty file modified experiments_plugin_input/r_basicpitch.py
100755 → 100644
Empty file.
Empty file modified experiments_plugin_input/r_color_art.py
100755 → 100644
Empty file.
49 changes: 37 additions & 12 deletions functions/audio.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,38 @@

import av
import os
import configparser
from os.path import exists
from tinydb import TinyDB, Query

audioinfo_cache_filepath = './__config/cache_audioinfo.db'
db = TinyDB(audioinfo_cache_filepath)
samplesdb = Query()

def get_audiofile_info(sample_filename):
audio_path = ''
audio_filesize = 0
audio_crc = 0
audio_moddate = 0
audio_duration = 0
audio_duration = 5
audio_timebase = 44100
audio_hz = 44100

if os.path.exists(sample_filename):
db_searchfound = db.search(samplesdb.path == sample_filename)

out_data = {}
out_data['path'] = sample_filename
out_data['file_size'] = 0
out_data['mod_date'] = 0
out_data['dur'] = 1
out_data['crc'] = 0
out_data['audio_timebase'] = 44100
out_data['rate'] = 44100
out_data['dur_sec'] = 1

if db_searchfound != []:
out_data = db_searchfound[0]

elif os.path.exists(sample_filename):
avdata = av.open(sample_filename)
audio_path = sample_filename
audio_filesize = os.path.getsize(sample_filename)
Expand All @@ -24,13 +45,17 @@ def get_audiofile_info(sample_filename):
audio_hz_b = avdata.streams.audio[0].rate
if audio_hz_b != None: audio_hz = audio_hz_b

out_data = {}
out_data['path'] = audio_path
out_data['file_size'] = audio_filesize
out_data['crc'] = audio_crc
out_data['mod_date'] = audio_moddate
out_data['dur'] = audio_duration
out_data['audio_timebase'] = audio_timebase
out_data['rate'] = audio_hz
out_data['dur_sec'] = (audio_duration/audio_timebase)
if db.search(samplesdb.path == audio_path) == []:
out_db_data = {}
out_db_data['path'] = audio_path
out_db_data['file_size'] = audio_filesize
out_db_data['mod_date'] = audio_moddate
out_db_data['dur'] = audio_duration
out_db_data['crc'] = 0
out_db_data['audio_timebase'] = audio_timebase
out_db_data['rate'] = audio_hz
out_db_data['dur_sec'] = (audio_duration/audio_timebase)
db.insert(out_db_data)
out_data = out_db_data

return out_data
Empty file modified functions/audio_wav.py
100755 → 100644
Empty file.
Empty file modified functions/auto.py
100755 → 100644
Empty file.
Empty file modified functions/colors.py
100755 → 100644
Empty file.
10 changes: 5 additions & 5 deletions functions/core.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ def convert_type_output(extra_json):
if out_type != 'debug':
convproj_j[0] = song_compat.makecompat(convproj_j[0], in_type, in_dawcapabilities, out_dawcapabilities)

if in_type == 'r':
convproj_j[0] = song_compat.makecompat_any(convproj_j[0], in_type, in_dawcapabilities, out_dawcapabilities)
if in_type in ['r', 'm']: convproj_j[0] = song_compat.makecompat_audiostretch(convproj_j[0], in_type, in_dawcapabilities, out_dawcapabilities)

convproj_j[0] = song_compat.makecompat_any(convproj_j[0], in_type, in_dawcapabilities, out_dawcapabilities)

if in_type == 'ri' and out_type == 'mi': convproj_j[0] = song_convert.ri2mi(convproj_j[0])
if in_type == 'ri' and out_type == 'r': convproj_j[0] = song_convert.ri2r(convproj_j[0])
Expand All @@ -196,9 +197,8 @@ def convert_type_output(extra_json):
if out_type != 'debug':
convproj_j[0] = song_compat.makecompat(convproj_j[0], out_type, in_dawcapabilities, out_dawcapabilities)

if in_type != 'r':
convproj_j[0] = song_compat.makecompat_any(convproj_j[0], out_type, in_dawcapabilities, out_dawcapabilities)

if out_type in ['r', 'm']: convproj_j[0] = song_compat.makecompat_audiostretch(convproj_j[0], out_type, in_dawcapabilities, out_dawcapabilities)

convproj_j[1] = currentplug_output[3]
convproj_j[2] = currentplug_output[4]

Expand Down
Empty file modified functions/data_bytes.py
100755 → 100644
Empty file.
58 changes: 57 additions & 1 deletion functions/data_values.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,60 @@ def sort_pos(datapart):


def list_chunks(i_list, i_amount):
return [i_list[i:i + i_amount] for i in range(0, len(i_list), i_amount)]
return [i_list[i:i + i_amount] for i in range(0, len(i_list), i_amount)]






def tempo_to_rate(i_in, i_mode):
if i_mode == True: return (120/i_in)
if i_mode == False: return (i_in/120)

def time_from_steps(i_dict, i_name, i_stretched, i_value, i_rate):
in_bpm = 1
in_stretch = 1

if i_rate != None: in_stretch = i_rate

if i_stretched == False:
out_nonstretch = i_value
out_normal = i_value*in_stretch
i_dict[i_name+'_nonstretch'] = out_nonstretch
i_dict[i_name] = out_normal
else:
out_nonstretch = i_value/in_stretch
out_normal = i_value
i_dict[i_name+'_nonstretch'] = i_value/in_stretch
i_dict[i_name] = i_value

out_real_nonstretch = (out_nonstretch/8)*in_bpm
out_real = out_real_nonstretch/in_stretch

i_dict[i_name+'_real_nonstretch'] = out_real_nonstretch
i_dict[i_name+'_real'] = out_real

def time_from_seconds(i_dict, i_name, i_stretched, i_value, i_rate):
in_bpm = 1
in_stretch = 1

if i_rate != None: in_stretch = i_rate

if i_stretched == False:
out_real_nonstretch = i_value
out_real = out_real_nonstretch/in_stretch
i_dict[i_name+'_real_nonstretch'] = out_real_nonstretch
i_dict[i_name+'_real'] = out_real

else:
out_real = i_value
out_real_nonstretch = out_real*in_stretch
i_dict[i_name+'_real_nonstretch'] = out_real_nonstretch
i_dict[i_name+'_real'] = out_real

out_nonstretch = (out_real_nonstretch*8)*in_bpm
out_normal = out_nonstretch*in_stretch

i_dict[i_name+'_nonstretch'] = out_nonstretch
i_dict[i_name] = out_normal
Empty file modified functions/folder_samples.py
100755 → 100644
Empty file.
Empty file modified functions/format_caustic.py
100755 → 100644
Empty file.
72 changes: 37 additions & 35 deletions functions/format_flp_dec.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ def calctempotimed(i_value):
#print('VALUE', str(i_value).ljust(20), '| MUL', str(i_tempomul).ljust(20), '| OUT', str(i_out).ljust(20))
return i_out

def decodetext(event_data):
return event_data.decode('utf-16le').rstrip('\x00\x00')

# ------------- parse -------------
def parse_arrangement(arrdata):

#print(FLSplitted)

bio_fldata = create_bytesio(arrdata)
output = []
while bio_fldata[0].tell() < bio_fldata[1]:
Expand All @@ -38,34 +43,26 @@ def parse_arrangement(arrdata):
placement['trackindex'] = int.from_bytes(bio_fldata[0].read(4), "little")
placement['unknown1'] = int.from_bytes(bio_fldata[0].read(2), "little")
placement['flags'] = int.from_bytes(bio_fldata[0].read(2), "little")
placement['unknown2'] = int.from_bytes(bio_fldata[0].read(2), "little")
placement['unknown3'] = int.from_bytes(bio_fldata[0].read(2), "little")
if FLSplitted[0] == '21':
placement['unknown4'] = bio_fldata[0].read(28)
placement['unknown2'] = int.from_bytes(bio_fldata[0].read(4), "little")

startoffset_bytes = bio_fldata[0].read(4)
endoffset_bytes = bio_fldata[0].read(4)

if FLSplitted[0] == '21':
startoffset_bytes = placement['unknown4'][0:4]
endoffset_bytes = placement['unknown4'][4:8]

placement['unknown3'] = bio_fldata[0].read(28)

startoffset = int.from_bytes(startoffset_bytes, "little")
endoffset = int.from_bytes(endoffset_bytes, "little")
startoffset_float = struct.unpack('<f', startoffset_bytes)[0]
endoffset_float = struct.unpack('<f', endoffset_bytes)[0]

if FLSplitted[0] == '21':
if placement['itemindex'] > placement['patternbase']:
if startoffset != 4294967295 and startoffset != 3212836864: placement['startoffset'] = startoffset
if endoffset != 4294967295 and endoffset != 3212836864: placement['endoffset'] = endoffset
if placement['itemindex'] > placement['patternbase']:
if startoffset != 4294967295 and startoffset != 3212836864: placement['startoffset'] = startoffset
if endoffset != 4294967295 and endoffset != 3212836864: placement['endoffset'] = endoffset
else:
if placement['itemindex'] > placement['patternbase']:
if startoffset != 4294967295 and startoffset != 3212836864: placement['startoffset'] = startoffset
if endoffset != 4294967295 and endoffset != 3212836864: placement['endoffset'] = endoffset
else:
if startoffset_float > 0: placement['startoffset'] = calctempotimed(startoffset_float)
if endoffset_float > 0: placement['endoffset'] = calctempotimed(endoffset_float)
#print(placement['length'], startoffset_float, endoffset_float)
if startoffset_float > 0: placement['startoffset'] = calctempotimed(startoffset_float)
if endoffset_float > 0: placement['endoffset'] = calctempotimed(endoffset_float)

output.append(placement)
return output
Expand Down Expand Up @@ -175,6 +172,7 @@ def parse_flevent(datastream):
def parse(inputfile):
global FL_Main
global FLSplitted

fileobject = open(inputfile, 'rb')
headername = fileobject.read(4)
rifftable = data_bytes.riff_read(fileobject, 0)
Expand Down Expand Up @@ -221,6 +219,10 @@ def parse(inputfile):
FL_FXCreationMode = 0
FL_TimeMarkers = {}
FL_ChanGroupName = []
T_FL_CurrentArrangement = '0'
FL_Arrangements[T_FL_CurrentArrangement] = {}
FL_Arrangements[T_FL_CurrentArrangement]['tracks'] = {}
FL_Arrangements[T_FL_CurrentArrangement]['items'] = {}
T_FL_FXNum = -1

for event in eventtable:
Expand All @@ -230,7 +232,7 @@ def parse(inputfile):
if event_id == 199:
FLVersion = event_data.decode('utf-8').rstrip('\x00')
FLSplitted = FLVersion.split('.')
if int(FLSplitted[0]) < 20:
if int(FLSplitted[0]) < 12:
print('[error] FL version '+FLSplitted[0]+' is not supported.')
exit()
FL_Main['Version'] = FLVersion
Expand All @@ -239,15 +241,15 @@ def parse(inputfile):
if event_id == 17: FL_Main['Numerator'] = event_data
if event_id == 18: FL_Main['Denominator'] = event_data
if event_id == 11: FL_Main['Shuffle'] = event_data
if event_id == 194: FL_Main['Title'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 206: FL_Main['Genre'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 207: FL_Main['Author'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 202: FL_Main['ProjectDataPath'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 195: FL_Main['Comment'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 197: FL_Main['URL'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 194: FL_Main['Title'] = decodetext(event_data)
if event_id == 206: FL_Main['Genre'] = decodetext(event_data)
if event_id == 207: FL_Main['Author'] = decodetext(event_data)
if event_id == 202: FL_Main['ProjectDataPath'] = decodetext(event_data)
if event_id == 195: FL_Main['Comment'] = decodetext(event_data)
if event_id == 197: FL_Main['URL'] = decodetext(event_data)
if event_id == 237: FL_Main['ProjectTime'] = event_data
if event_id == 10: FL_Main['ShowInfo'] = event_data
if event_id == 231: FL_ChanGroupName.append(event_data.decode('utf-16le').rstrip('\x00\x00'))
if event_id == 231: FL_ChanGroupName.append(decodetext(event_data))

if event_id == 65:
T_FL_CurrentPattern = event_data
Expand Down Expand Up @@ -296,7 +298,7 @@ def parse(inputfile):
if event_data != 5328737:
FL_Patterns[str(T_FL_CurrentPattern)]['color'] = event_data
if event_id == 193:
FL_Patterns[str(T_FL_CurrentPattern)]['name'] = event_data.decode('utf-16le').rstrip('\x00\x00')
FL_Patterns[str(T_FL_CurrentPattern)]['name'] = decodetext(event_data)

if event_id == 99:
T_FL_CurrentArrangement = event_data
Expand All @@ -308,7 +310,7 @@ def parse(inputfile):
FL_TimeMarkers = FL_Arrangements[str(T_FL_CurrentArrangement)]['timemarkers']
TimeMarker_id = 0
if event_id == 241:
FL_Arrangements[str(T_FL_CurrentArrangement)]['name'] = event_data.decode('utf-16le').rstrip('\x00\x00')
FL_Arrangements[str(T_FL_CurrentArrangement)]['name'] = decodetext(event_data)
if event_id == 233:
playlistitems = parse_arrangement(event_data)
FL_Arrangements[str(T_FL_CurrentArrangement)]['items'] = playlistitems
Expand All @@ -322,7 +324,7 @@ def parse(inputfile):
if event_id == 239: #PLTrackName
if str(currenttracknum) not in FL_Tracks:
FL_Tracks[str(currenttracknum)] = {}
FL_Tracks[str(currenttracknum)]['name'] = event_data.decode('utf-16le').rstrip('\x00\x00')
FL_Tracks[str(currenttracknum)]['name'] = decodetext(event_data)


if event_id == 148:
Expand All @@ -335,7 +337,7 @@ def parse(inputfile):
FL_TimeMarkers[str(T_FL_CurrentTimeMarker)]['type'] = timemarkertype
FL_TimeMarkers[str(T_FL_CurrentTimeMarker)]['pos'] = timemarkertime
if event_id == 205:
event_text = event_data.decode('utf-16le').rstrip('\x00\x00')
event_text = decodetext(event_data)
#print('\\__TimeMarkerName:', event_text)
FL_TimeMarkers[str(T_FL_CurrentTimeMarker)]['name'] = event_text
if event_id == 33:
Expand Down Expand Up @@ -364,7 +366,7 @@ def parse(inputfile):
T_FL_FXIcon = None
if FL_FXCreationMode == 0:
if event_id == 201:
event_text = event_data.decode('utf-16le').rstrip('\x00\x00')
event_text = decodetext(event_data)
#print('\\__DefPluginName:', event_text)
DefPluginName = event_text
if event_id == 212:
Expand All @@ -374,7 +376,7 @@ def parse(inputfile):
#print(event_data)

if event_id == 203:
event_text = event_data.decode('utf-16le').rstrip('\x00\x00')
event_text = decodetext(event_data)
#print('\\__PluginName:', event_text)
FL_Channels[str(T_FL_CurrentChannel)]['name'] = event_text
if event_id == 155:
Expand Down Expand Up @@ -416,7 +418,7 @@ def parse(inputfile):
if event_id == 20: FL_Channels[str(T_FL_CurrentChannel)]['looptype'] = event_data
if event_id == 135: FL_Channels[str(T_FL_CurrentChannel)]['middlenote'] = event_data
if event_id == 196:
samplefilename = event_data.decode('utf-16le').rstrip('\x00\x00')
samplefilename = decodetext(event_data)
if samplefilename[:21] == '%FLStudioFactoryData%':
samplefilename = "C:\\Program Files\\Image-Line\\FL Studio 20" + samplefilename[21:]
FL_Channels[str(T_FL_CurrentChannel)]['samplefilename'] = samplefilename
Expand All @@ -439,7 +441,7 @@ def parse(inputfile):
T_FL_FXColor = None
T_FL_FXIcon = None
if event_id == 201:
event_text = event_data.decode('utf-16le').rstrip('\x00\x00')
event_text = decodetext(event_data)
#print('\\__DefPluginName:', event_text)
DefPluginName = event_text
if event_id == 212:
Expand All @@ -449,7 +451,7 @@ def parse(inputfile):
FXPlugin['data'] = event_data
if event_id == 155: FXPlugin['icon'] = event_data
if event_id == 128: FXPlugin['color'] = event_data
if event_id == 203: FXPlugin['name'] = event_data.decode('utf-16le').rstrip('\x00\x00')
if event_id == 203: FXPlugin['name'] = decodetext(event_data)
if event_id == 98: #FXToSlotNum
FL_Mixer[str(T_FL_FXNum)]['slots'][event_data] = FXPlugin
FXPlugin = None
Expand All @@ -458,7 +460,7 @@ def parse(inputfile):
if event_id == 154: FL_Mixer[str(T_FL_FXNum)]['inchannum'] = event_data
if event_id == 147: FL_Mixer[str(T_FL_FXNum)]['outchannum'] = event_data
if event_id == 204:
event_text = event_data.decode('utf-16le').rstrip('\x00\x00')
event_text = decodetext(event_data)
FL_Mixer[str(T_FL_FXNum+1)]['name'] = event_text

output = {}
Expand Down
Loading

0 comments on commit 9d2397b

Please sign in to comment.