def test_als9_noauto(): fname = f'{TESTS_DIR_ALS}/live9/live9-patch-markers-noauto.als' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() print(proj.markers) print(proj.tempo_automation_events) marks = [ Marker(time=14.222222222222221, text='Live9Marker'), Marker(time=28.444444444444443, text='Live9Marker2'), Marker(time=56.888888888888886, text='Live9Marker3') ] auto = [ TempoAutomationFloatEvent(id=None, time=-63072000.0, real_time=None, value=135.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None) ] assert proj.markers == marks assert proj.tempo_automation_events == auto
def test_als8_noauto(): fname = f'{TESTS_DIR_ALS}/live8/live8-patch-markers-noauto.als' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() print(proj.markers) print(proj.tempo_automation_events) marks = [ Marker(time=125.91815320041972, text='b'), Marker(time=200.20986358866736, text='c') ] auto = [ TempoAutomationFloatEvent(id=None, time=-63072000.0, real_time=None, value=95.3, curve_control1=None, curve_control2=None, prev_aligned_bpm=None) ] assert proj.markers == marks assert proj.tempo_automation_events == auto
def test_als120(): fname = f'{TESTS_DIR_ALS}/example-120.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() markers = proj.markers assert proj.version == AbletonSetVersion( major='5', minor='10.0_377', minorA=10, minorB=0, minorC=377, schema_change_count='3', creator='Ableton Live 10.1.7', revision='f7eb4c8e0a49802359f4e078b341fdfb9d547a77') assert [m.time for m in markers] == [ 0.0, 200.0000133333342, 216.00001440000096, 324.00002160000145, 464.0000309333354, 604.0000402666693, 716.0000477333365, 840.0000560000037, 1000.000066666671, 1189.053707412938, 1392.000092800006, 1512.0001008000067, 1656.0001104000073, 1792.0001194666745, 3904.0002602666837 ] assert [m.text for m in markers] == [ 'mirvs - his track你好', 'comfort - other track', 'comfort - yo', 'sh1n - track', 'stm - ggr', 'heart - ID', 'ID - ID', '', '', 'track - this track', 'another track', 'another track', 'another track', 'tids track', 'sd' ] assert [format_time(m.time) for m in markers] == [ '00:00', '03:20', '03:36', '05:24', '07:44', '10:04', '11:56', '14:00', '16:40', '19:49', '23:12', '25:12', '27:36', '29:52', '65:04' ]
def test_flp_markers(): """ Test that we parse and correctly id markers of various action types. Test that we only look at "None" markers when computing the marker times. """ fname = f'{TESTS_DIR}/fl/fl-markers.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=False) proj.parse() print(proj.raw_markers) raw = [ FlStudioRawMarker(time=1220, text='Auto', action=0), FlStudioRawMarker(time=1356, text='start', action=5), FlStudioRawMarker(time=1932, text='time sig', action=8), FlStudioRawMarker(time=2624, text='loop', action=4), FlStudioRawMarker(time=3168, text='marker loop', action=1), FlStudioRawMarker(time=3988, text='marker skip', action=2), FlStudioRawMarker(time=4896, text='marker pause', action=3), FlStudioRawMarker(time=5640, text='punch in', action=9), FlStudioRawMarker(time=6516, text='punch out', action=10) ] assert proj.raw_markers == raw print(proj.markers) m = [Marker(time=5.865384615384616, text='Auto')] assert proj.markers == m
def test_cue_rb(): fname = f'{TESTS_DIR_CUE}/rekordbox.cue' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() markers = proj.markers assert markers == [CueRawMarker(time=1, text='comfort - ambeat', performer=None, title='comfort - ambeat', index_num=1, orig_index='00:00:01', file='/Users/mark/Music/Ableton/ambeat Project/comfort - ambeat.mp3', file_type='WAVE'), CueRawMarker(time=18, text='Unknown Artist - REC-2020-03-11', performer='Unknown Artist', title='REC-2020-03-11', index_num=1, orig_index='00:00:18', file='/Users/mark/Music/PioneerDJ/Recording/Unknown Artist/Unknown Album/01 REC-2020-03-11.wav', file_type='WAVE')]
def test_cue_rb2(): fname = f'{TESTS_DIR_CUE}/rekordbox2.cue' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() markers = proj.markers assert markers == [CueRawMarker(time=0, text='comfort - ambeat', performer=None, title='comfort - ambeat', index_num=1, orig_index='00:00:00', file='/Users/mark/Music/Ableton/ambeat Project/comfort - ambeat.mp3', file_type='WAVE'), CueRawMarker(time=11, text='comfort - more than a memory', performer=None, title='comfort - more than a memory', index_num=1, orig_index='00:00:11', file='/Users/mark/Music/Ableton/dan shay Project/comfort - more than a memory.mp3', file_type='WAVE')]
def test_cue_standard(): fname = f'{TESTS_DIR_CUE}/djdementia.cue' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() markers = proj.markers assert markers == [CueRawMarker(time=0, text='Love and Rockets - So Alive', performer='Love and Rockets', title='So Alive', index_num=1, orig_index='00:00:00', file=None, file_type=None), CueRawMarker(time=243, text='Nitzer Ebb - Join In The Chant', performer='Nitzer Ebb', title='Join In The Chant', index_num=1, orig_index='04:03:19', file=None, file_type=None), CueRawMarker(time=592, text='Sisters of Mercy - Dominion Mother Russia', performer='Sisters of Mercy', title='Dominion Mother Russia', index_num=1, orig_index='09:52:70', file=None, file_type=None), CueRawMarker(time=980, text="Information Society - What's On Your Mind (Pure Energy)", performer='Information Society', title="What's On Your Mind (Pure Energy)", index_num=1, orig_index='16:20:21', file=None, file_type=None), CueRawMarker(time=1217, text='Nine Inch Nails - Down In It Singe', performer='Nine Inch Nails', title='Down In It Singe', index_num=1, orig_index='20:17:07', file=None, file_type=None), CueRawMarker(time=1635, text='Iggy Pop - Lust For Life', performer='Iggy Pop', title='Lust For Life', index_num=1, orig_index='27:15:23', file=None, file_type=None), CueRawMarker(time=1930, text='Talking Heads - Psycho Killer', performer='Talking Heads', title='Psycho Killer', index_num=1, orig_index='32:10:67', file=None, file_type=None), CueRawMarker(time=2176, text='Arnaud Rebotini - Pagan Dance Move', performer='Arnaud Rebotini', title='Pagan Dance Move', index_num=1, orig_index='36:16:07', file=None, file_type=None), CueRawMarker(time=2591, text='3TEETH - Pearls 2 Swine (Mr. Skeleton Remix)', performer='3TEETH', title='Pearls 2 Swine (Mr. Skeleton Remix)', index_num=1, orig_index='43:11:58', file=None, file_type=None), CueRawMarker(time=2829, text='Front Line Assembly - Circuitry', performer='Front Line Assembly', title='Circuitry', index_num=1, orig_index='47:09:61', file=None, file_type=None), CueRawMarker(time=3159, text='The Cramps - Bikini Girls with Machine Guns', performer='The Cramps', title='Bikini Girls with Machine Guns', index_num=1, orig_index='52:39:14', file=None, file_type=None), CueRawMarker(time=3342, text="DAF - Als War's Das Letzte Mal", performer='DAF', title="Als War's Das Letzte Mal", index_num=1, orig_index='55:42:41', file=None, file_type=None), CueRawMarker(time=3535, text='Fad Gadget - Collapsing New People', performer='Fad Gadget', title='Collapsing New People', index_num=1, orig_index='58:55:07', file=None, file_type=None), CueRawMarker(time=3777, text='Louisahhh - Feral Rhythm', performer='Louisahhh', title='Feral Rhythm', index_num=1, orig_index='62:57:69', file=None, file_type=None), CueRawMarker(time=4000, text='Radical G, The Horrorist - Here Comes The Storm Kobosil 44 Terror Mix', performer='Radical G, The Horrorist', title='Here Comes The Storm Kobosil 44 Terror Mix', index_num=1, orig_index='66:40:33', file=None, file_type=None), CueRawMarker(time=4300, text='Tones on Tail - Go!', performer='Tones on Tail', title='Go!', index_num=1, orig_index='71:40:73', file=None, file_type=None), CueRawMarker(time=4549, text='Ministry - We Believe', performer='Ministry', title='We Believe', index_num=1, orig_index='75:49:25', file=None, file_type=None), CueRawMarker(time=4675, text='VoX LoW - Something Is Wrong', performer='VoX LoW', title='Something Is Wrong', index_num=1, orig_index='77:55:03', file=None, file_type=None), CueRawMarker(time=4994, text='Lydia Lunch - Spooky', performer='Lydia Lunch', title='Spooky', index_num=1, orig_index='83:14:52', file=None, file_type=None), CueRawMarker(time=5138, text='Peter Murphy - All Night Long', performer='Peter Murphy', title='All Night Long', index_num=1, orig_index='85:38:64', file=None, file_type=None), CueRawMarker(time=5464, text='Killing Joke - Love Like Blood', performer='Killing Joke', title='Love Like Blood', index_num=1, orig_index='91:04:30', file=None, file_type=None), CueRawMarker(time=5763, text='The Cramps - Strychnine', performer='The Cramps', title='Strychnine', index_num=1, orig_index='96:03:19', file=None, file_type=None), CueRawMarker(time=5899, text='The Normal - Warm Leatherette', performer='The Normal', title='Warm Leatherette', index_num=1, orig_index='98:19:32', file=None, file_type=None)]
def test_cue_emit2(): fname = f'{TESTS_DIR_CUE}/comfort_mini.cue' correct = f'{TESTS_DIR_CUE}/comfort_mini.emit.cue' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() assert proj.emit() == open(correct).read()
def test_als_automation_theo(): fname = f'{TESTS_DIR_ALS}/automation.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() auto = [ TempoAutomationFloatEvent(id='92', time=-63072000.0, real_time=0.0, value=60.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='290', time=4.0, real_time=4.0, value=60.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='291', time=8.0, real_time=6.772588722239782, value=120.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='596', time=12.0, real_time=8.305065593537753, value=200.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None) ] marks = [ Marker(time=0.0, text='A'), Marker(time=4.0, text='B'), Marker(time=5.6218604324326575, text='D'), Marker(time=6.772588722239782, text='C'), Marker(time=7.635634939595124, text='Z'), Marker(time=8.905065593537753, text='E') ] assert proj.tempo_automation_events == auto assert proj.markers == marks
def test_als8_auto(): fname = f'{TESTS_DIR_ALS}/live8/live8-patch-markers-auto.als' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() print(proj.markers) print(proj.tempo_automation_events) marks = [ Marker(time=81.09683000726724, text='b'), Marker(time=125.34683000726724, text='c') ] auto = [ TempoAutomationFloatEvent(id=None, time=-63072000.0, real_time=0.0, value=95.3, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id=None, time=0.0, real_time=0.0, value=95.3, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id=None, time=4.0, real_time=2.103149251721395, value=138.3, curve_control1=None, curve_control2=None, prev_aligned_bpm=95.3), TempoAutomationFloatEvent(id=None, time=200.0, real_time=81.09683000726724, value=160.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=138.3) ] assert proj.markers == marks assert proj.tempo_automation_events == auto
def test_als9_auto(): fname = f'{TESTS_DIR_ALS}/live9/live9-patch-2-0point.als' with open(fname, 'rb') as f: proj = load_project(fname, f) proj.parse() print(proj.markers) print(proj.tempo_automation_events) marks = [ Marker(time=11.169835008759637, text='Live9Marker'), Marker(time=22.141263580188213, text='Live9Marker2'), Marker(time=44.08412072304535, text='Live9Marker3') ] auto = [ TempoAutomationFloatEvent(id=None, time=-63072000.0, real_time=0.0, value=135.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id=None, time=0.0, real_time=0.0, value=135.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id=None, time=4.0, real_time=1.5698350087596382, value=175.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=135.0) ] assert proj.markers == marks assert proj.tempo_automation_events == auto
def test_als_auto_pathological3_daw(): """ 25505 automation points,no slopes, just horizontal and vertical lines stress testing alignment """ fname = f'{TESTS_DIR_ALS}/automation-pathological-end3.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=False) proj.parse() assert proj.markers == [ Marker(time=447.53153265863915, text='A'), Marker(time=466.60806196643625, text='X'), Marker(time=486.1465317732963, text='B'), Marker(time=495.56805602397407, text='D'), Marker(time=505.2425003381325, text='C'), Marker(time=517.7672955377825, text='Z'), Marker(time=525.4196287976511, text='1'), Marker(time=539.046232416382, text='E'), Marker(time=549.6099694804802, text='YY') ]
def main(): fname = args.file try: # markers are raw time data. it's up to the client to determine how to # present it with open(fname, 'rb') as f: # markers = dawtool.extract_markers(fname, f) proj = load_project(fname, f, theoretical=args.theoretical) proj.parse() # print(len(proj.tempo_automation_events)) markers = proj.markers except FileNotFoundError: print(fname, 'not found') return except UnknownExtension as e: print('unknown ext', e) return except ValueError as e: print('Could not extract markers from', fname, ':', e) raise if args.verbose: proj.dump() if args.markers: # There was no error, but no markers if not markers: print('Could not find markers in', fname) return for m in markers: print(format_time(m.time, args.hours, precise=args.imprecise), m.text) if args.emit: print(proj.emit(), end='')
def test_flp_auto_basic2_theo(): fname = f'{TESTS_DIR}/fl/auto-basic2.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() print(proj.tempo_automation_events) print(proj.markers) auto = [ ArtificialGlobalTempoAutomationPoint(beat=0.0, real_time=0.0, bpm=106.48648738861084, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=0.9270833333333334, real_time=0.5223667468436876, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=4.984892686208089, real_time=2.398727645463972, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=7.145833333333333, real_time=3.2288451006413315, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=7.145833333333333, real_time=3.2288451006413315, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=11.203642686208088, real_time=5.1052059992616154, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=14.458333333333334, real_time=6.355483521217345, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=14.458333333333334, real_time=6.355483521217345, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=18.51614268620809, real_time=8.23184441983763, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=20.052083333333332, real_time=8.821870408284491, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=20.052083333333332, real_time=8.821870408284491, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=24.109892686208088, real_time=10.698231306904775, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=25.28125, real_time=11.148203939758847, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=25.28125, real_time=11.148203939758847, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=29.339059352874756, real_time=13.024564838379131, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=30.583333333333332, real_time=13.502548142351761, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=30.583333333333332, real_time=13.502548142351761, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=34.641142686208084, real_time=15.378909040972044, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=43.666666666666664, real_time=18.846031105739364, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=43.666666666666664, real_time=18.846031105739364, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=47.72447601954142, real_time=20.722392004359648, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=None) ] markers = [ Marker(time=14.464036142744112, text='Auto'), Marker(time=16.46912558510744, text='ASDF'), Marker(time=20.980291463829325, text='MM') ] assert proj.tempo_automation_events == auto assert proj.markers == markers
def test_als_automation_intense_theo(): fname = f'{TESTS_DIR_ALS}/automation-intense.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() # auto = [TempoAutomationFloatEvent(id='598', time=-63072000.0, real_time=0.0, value=120.760574, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='597', time=2.0, real_time=0.9937018020467507, value=120.760574, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='290', time=4.0, real_time=2.4905527030701258, value=60.0, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='600', time=5.0, real_time=3.5868133818231116, value=50.3135643, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='599', time=6.5, real_time=4.838676372461883, value=125.883995, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='601', time=7.25, real_time=5.57897557720625, value=40.0667267, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='291', time=8.0, real_time=6.32803879569597, value=120.0, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='602', time=8.5, real_time=6.534582951935399, value=183.949417, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='603', time=9.5, real_time=7.251625196560135, value=54.1561279, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='596', time=12.0, real_time=9.011510026924826, value=200.0, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='604', time=13.0, real_time=9.563386505013117, value=74.6498032, curve_control1=None, curve_control2=None), TempoAutomationFloatEvent(id='605', time=15.25, real_time=10.924744397672802, value=147.658524, curve_control1=None, curve_control2=None)] # marks = [Marker(time=0.0, text='A'), Marker(time=0.7452763515350631, text='X'), Marker(time=2.4905527030701258, text='B'), Marker(time=4.481006849648747, text='D'), Marker(time=6.32803879569597, text='C'), Marker(time=7.708620375464505, text='Z'), Marker(time=8.710756906470802, text='1'), Marker(time=10.245379935705511, text='E'),Marker(time=12.042187505799767, text='YY')] auto = [ TempoAutomationFloatEvent(id='598', time=-63072000.0, real_time=0.0, value=120.760574, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='597', time=2.0, real_time=0.9937018020467507, value=120.760574, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='290', time=4.0, real_time=2.3751211991079835, value=60.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='600', time=5.0, real_time=3.4657381748335556, value=50.3135643, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='599', time=6.5, real_time=4.557934529843792, value=125.883995, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='601', time=7.25, real_time=5.158240936269706, value=40.0667267, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='291', time=8.0, real_time=5.775787872079139, value=120.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='602', time=8.5, real_time=5.976181756557032, value=183.949417, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='603', time=9.5, real_time=6.541445040210277, value=54.1561279, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='596', time=12.0, real_time=7.885121207824302, value=200.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='604', time=13.0, real_time=8.356844190648877, value=74.6498032, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='605', time=15.25, real_time=9.618101061558722, value=147.658524, curve_control1=None, curve_control2=None, prev_aligned_bpm=None) ] marks = [ Marker(time=0.0, text='A'), Marker(time=0.7452763515350631, text='X'), Marker(time=2.3751211991079835, text='B'), Marker(time=4.292025681716721, text='D'), Marker(time=5.775787872079139, text='C'), Marker(time=6.984600086821905, text='Z'), Marker(time=7.722987605556904, text='1'), Marker(time=9.024251745511293, text='E'), Marker(time=10.735544169685687, text='YY') ] assert proj.markers == marks assert proj.tempo_automation_events == auto
def test_flp_auto_complex_theo(): fname = f'{TESTS_DIR}/fl/complex.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() print(proj.tempo_automation_events) print(proj.markers) auto = [ GlobalTempoAutomationPoint(beat=0.0, real_time=0.0, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=1.6458414793014526, real_time=0.9123849810850921, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=2.959980010986328, real_time=1.7283322853130831, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=6.625, real_time=3.8670974037809733, bpm=102.81690001487732, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=6.625, real_time=3.8670974037809733, bpm=120.0, track_id=2, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=11.841332912445068, real_time=6.01160364583677, bpm=175.38461208343506, track_id=2, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=13.041666666666666, real_time=6.422244148431342, bpm=175.38461208343506, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=13.041666666666666, real_time=6.422244148431342, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=14.454412619272867, real_time=7.101860584876991, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=16.589843908945717, real_time=8.129132473842393, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=17.115885535875954, real_time=8.450819383229293, bpm=75.59055089950562, track_id=4, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=17.810966531435646, real_time=8.852371580604116, bpm=138.42519521713257, track_id=4, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=22.072916666666668, real_time=10.699701524497247, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=22.072916666666668, real_time=10.699701524497247, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=23.48566261927287, real_time=11.379317960942895, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=25.62109390894572, real_time=12.406589849908297, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=26.147135535875957, real_time=12.728276759295197, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=26.84221653143565, real_time=13.12982895667002, bpm=138.42519521713257, track_id=3, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=33.541666666666664, real_time=16.033686216783245, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=33.541666666666664, real_time=16.033686216783245, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=34.954412619272865, real_time=16.713302653228894, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=37.08984390894572, real_time=17.740574542194295, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=37.615885535875954, real_time=18.062261451581197, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=38.310966531435646, real_time=18.46381364895602, bpm=138.42519521713257, track_id=3, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=39.833333333333336, real_time=19.12367913060178, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=39.833333333333336, real_time=19.12367913060178, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=41.47917481263479, real_time=20.036064111686873, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=42.793313344319664, real_time=20.852011415914863, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=50.541666666666664, real_time=25.37365327900887, bpm=102.81690001487732, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=50.541666666666664, real_time=25.37365327900887, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=51.954412619272865, real_time=26.05326971545452, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=54.08984390894572, real_time=27.08054160441992, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=54.615885535875954, real_time=27.402228513806822, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=None), ArtificialGlobalTempoAutomationPoint(beat=54.895833333333336, real_time=27.5938950362706, bpm=100.89755884981437, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=54.895833333333336, real_time=27.5938950362706, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=56.54167481263479, real_time=28.506280017355692, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=57.855813344319664, real_time=29.322227321583682, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=None) ] markers = [ Marker(time=29.04176593744516, text='Auto'), Marker(time=32.31201984884661, text='ASDF'), Marker(time=35.223749340366794, text='MM') ] assert proj.tempo_automation_events == auto assert proj.markers == markers
def test_flp_auto_complex_daw(): fname = f'{TESTS_DIR}/fl/complex.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=False) proj.parse() print(proj.tempo_automation_events) print(proj.markers) assert proj.tempo_automation_events == [ GlobalTempoAutomationPoint(beat=0.0, real_time=0.0, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=1.6458414793014526, real_time=0.911635230481727, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=90.82207798054122), GlobalTempoAutomationPoint(beat=2.959980010986328, real_time=1.7278841654056063, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=102.75371602927872), ArtificialGlobalTempoAutomationPoint( beat=6.625, real_time=3.866649627455197, bpm=102.81690001487732, track_id=None, prev_aligned_bpm=102.81690001487732), GlobalTempoAutomationPoint(beat=6.625, real_time=3.866649627455197, bpm=120.0, track_id=2, prev_aligned_bpm=102.81690001487732), GlobalTempoAutomationPoint(beat=11.841332912445068, real_time=6.011772630351835, bpm=175.38461208343506, track_id=2, prev_aligned_bpm=175.32732608763763), ArtificialGlobalTempoAutomationPoint( beat=13.041666666666666, real_time=6.422413403125042, bpm=175.38461208343506, track_id=None, prev_aligned_bpm=175.38461208343506), GlobalTempoAutomationPoint(beat=13.041666666666666, real_time=6.422413403125042, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=175.38461208343506), GlobalTempoAutomationPoint(beat=14.454412619272867, real_time=7.101306113814689, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=16.589843908945717, real_time=8.128578002780092, bpm=124.72440719604492, track_id=4, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=17.115885535875954, real_time=8.449053473364255, bpm=75.59055089950562, track_id=4, prev_aligned_bpm=76.19865436084064), GlobalTempoAutomationPoint(beat=17.810966531435646, real_time=8.852002840907348, bpm=138.42519521713257, track_id=4, prev_aligned_bpm=137.85757689719802), ArtificialGlobalTempoAutomationPoint( beat=22.072916666666668, real_time=10.699335521560686, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=22.072916666666668, real_time=10.699335521560686, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=23.48566261927287, real_time=11.378703970971651, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=25.62109390894572, real_time=12.405975859937055, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=26.147135535875957, real_time=12.726451330521218, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=76.19865436084096), GlobalTempoAutomationPoint(beat=26.84221653143565, real_time=13.12940069806431, bpm=138.42519521713257, track_id=3, prev_aligned_bpm=137.8575768971977), ArtificialGlobalTempoAutomationPoint( beat=33.541666666666664, real_time=16.03326069493774, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=33.541666666666664, real_time=16.03326069493774, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=34.954412619272865, real_time=16.712629144348707, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=37.08984390894572, real_time=17.73990103331411, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=37.615885535875954, real_time=18.060376503898272, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=76.19865436084064), GlobalTempoAutomationPoint(beat=38.310966531435646, real_time=18.463325871441363, bpm=138.42519521713257, track_id=3, prev_aligned_bpm=137.85757689719802), ArtificialGlobalTempoAutomationPoint( beat=39.833333333333336, real_time=19.123194089847328, bpm=138.42519521713257, track_id=None, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=39.833333333333336, real_time=19.123194089847328, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=138.42519521713257), GlobalTempoAutomationPoint(beat=41.47917481263479, real_time=20.034736876644555, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=90.76324425465822), GlobalTempoAutomationPoint(beat=42.793313344319664, real_time=20.850985577344076, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=102.77771914604848), ArtificialGlobalTempoAutomationPoint( beat=50.541666666666664, real_time=25.372628232782063, bpm=102.81690001487732, track_id=None, prev_aligned_bpm=102.81690001487732), GlobalTempoAutomationPoint(beat=50.541666666666664, real_time=25.372628232782063, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=102.81690001487732), GlobalTempoAutomationPoint(beat=51.954412619272865, real_time=26.052778528795397, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=54.08984390894572, real_time=27.0800504177608, bpm=124.72440719604492, track_id=3, prev_aligned_bpm=124.72440719604492), GlobalTempoAutomationPoint(beat=54.615885535875954, real_time=27.400525888344962, bpm=75.59055089950562, track_id=3, prev_aligned_bpm=76.19865436084064), ArtificialGlobalTempoAutomationPoint( beat=54.895833333333336, real_time=27.592956291283517, bpm=100.89755884981437, track_id=None, prev_aligned_bpm=100.42673059443348), GlobalTempoAutomationPoint(beat=54.895833333333336, real_time=27.592956291283517, bpm=127.88732528686523, track_id=1, prev_aligned_bpm=100.42673059443348), GlobalTempoAutomationPoint(beat=56.54167481263479, real_time=28.50492617024704, bpm=90.70422649383545, track_id=1, prev_aligned_bpm=90.76324425465822), GlobalTempoAutomationPoint(beat=57.855813344319664, real_time=29.32117487094656, bpm=102.81690001487732, track_id=1, prev_aligned_bpm=102.77771914604848) ] marks = [ Marker(time=29.040613113158678, text='Auto'), Marker(time=32.310968190553474, text='ASDF'), Marker(time=35.22269768207366, text='MM') ] assert proj.markers == marks
def test_flp_auto_basic_theo(): fname = f'{TESTS_DIR}/fl/auto-basic.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse() print(proj.channels) assert proj.channels == [ Channel( id=0, name='Kick', sample_path= '%FLStudioFactoryData%/Data/Patches/Packs/Legacy/Drums/Dance/Kick Basic.wav', automation_points=[]), Channel( id=1, name='Clap', sample_path= '%FLStudioFactoryData%/Data/Patches/Packs/Legacy/Drums/Dance/Clap Basic.wav', automation_points=[]), Channel( id=2, name='Hat', sample_path= '%FLStudioFactoryData%/Data/Patches/Packs/Legacy/Drums/Dance/Hat Basic.wav', automation_points=[]), Channel( id=3, name='Snare', sample_path= '%FLStudioFactoryData%/Data/Patches/Packs/Legacy/Drums/Dance/Snare Basic.wav', automation_points=[]), Channel( id=4, name='coin 4', sample_path= '/Users/mark/Music/recording/samples/_drumkits/alucard's\u3000ice\u3000castle\u3000drum\u3000kit/_sfx_/random fx I mostly use/coin.wav', automation_points=[]), Channel(id=5, name='Tempo 5', sample_path=None, automation_points=[ ChannelAutomationPoint(beat_increment=0.0, value=0.5, tension=0.0, unknown3=b'\x00\x00\x00', direction=0), ChannelAutomationPoint(beat_increment=1.2499998807907104, value=0.5, tension=0.0, unknown3=b'\x00\x00\x00', direction=2) ]), Channel(id=6, name='Tempo 6', sample_path=None, automation_points=[ ChannelAutomationPoint(beat_increment=0.0, value=0.5833333134651184, tension=0.0, unknown3=b'\x00\x00\x00', direction=0), ChannelAutomationPoint(beat_increment=4.75, value=0.3076923191547394, tension=0.0, unknown3=b'\x00\x00\x00', direction=2) ]) ] print(proj.playlist_items) assert proj.playlist_items == [ PlaylistItem(start_pulse=0, channel_id=5, len_pulses=456, track_id=1, flags=64), PlaylistItem(start_pulse=0, channel_id=4, len_pulses=192, track_id=3, flags=64), PlaylistItem(start_pulse=752, channel_id=6, len_pulses=456, track_id=2, flags=64), PlaylistItem(start_pulse=1376, channel_id=5, len_pulses=456, track_id=1, flags=64) ]
def test_flp_auto_basic2_daw(): fname = f'{TESTS_DIR}/fl/auto-basic2.flp' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=False) proj.parse() print(proj.tempo_automation_events) print(proj.markers) events = [ ArtificialGlobalTempoAutomationPoint(beat=0.0, real_time=0.0, bpm=106.48648738861084, track_id=None, prev_aligned_bpm=None), GlobalTempoAutomationPoint(beat=0.9270833333333334, real_time=0.5223667468436876, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=106.48648738861084), GlobalTempoAutomationPoint(beat=4.984892686208089, real_time=2.3994277372238053, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.1841329103173), ArtificialGlobalTempoAutomationPoint( beat=7.145833333333333, real_time=3.229545306174421, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=7.145833333333333, real_time=3.229545306174421, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=11.203642686208088, real_time=5.106139355343321, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.18413291031732), ArtificialGlobalTempoAutomationPoint( beat=14.458333333333334, real_time=6.356416991072306, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=14.458333333333334, real_time=6.356416991072306, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=18.51614268620809, real_time=8.233011040241207, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.18413291031726), ArtificialGlobalTempoAutomationPoint( beat=20.052083333333332, real_time=8.823037142461324, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=20.052083333333332, real_time=8.823037142461324, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=24.109892686208088, real_time=10.699631191630225, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.18413291031732), ArtificialGlobalTempoAutomationPoint( beat=25.28125, real_time=11.149603938257552, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=25.28125, real_time=11.149603938257552, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=29.339059352874756, real_time=13.026665204429104, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.15223454990542), ArtificialGlobalTempoAutomationPoint( beat=30.583333333333332, real_time=13.504648949660437, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=30.583333333333332, real_time=13.504648949660437, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=34.641142686208084, real_time=15.381242998829336, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.18413291031735), ArtificialGlobalTempoAutomationPoint( beat=43.666666666666664, real_time=18.848365177369914, bpm=156.1904740333557, track_id=None, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=43.666666666666664, real_time=18.848365177369914, bpm=106.48648738861084, track_id=1, prev_aligned_bpm=156.1904740333557), GlobalTempoAutomationPoint(beat=47.72447601954142, real_time=20.7244921622086, bpm=156.1904740333557, track_id=1, prev_aligned_bpm=156.12033618949357) ] marks = [ Marker(time=14.466061944142794, text='Auto'), Marker(time=16.47145965673799, text='ASDF'), Marker(time=20.98239198176239, text='MM') ] assert proj.tempo_automation_events == events assert proj.markers == marks
def test_als_auto_unaligned_daw(): 'als with many points, fairly steep slopes, and points unaligned on 16th notes' fname = f'{TESTS_DIR_ALS}/automation-intense-unaligned.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=False) proj.parse() print(proj.tempo_automation_events) auto = [ TempoAutomationFloatEvent(id='598', time=-63072000.0, real_time=0.0, value=120.760574, curve_control1=None, curve_control2=None, prev_aligned_bpm=None), TempoAutomationFloatEvent(id='649', time=1.8125, real_time=0.9005422581048679, value=120.760574, curve_control1=None, curve_control2=None, prev_aligned_bpm=120.760574), TempoAutomationFloatEvent(id='667', time=4.0625, real_time=2.3966117557062345, value=60.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=61.687793722222224), TempoAutomationFloatEvent(id='669', time=4.093925345487846, real_time=2.427177295750691, value=80.6271286, curve_control1=None, curve_control2=None, prev_aligned_bpm=61.687793722222224), TempoAutomationFloatEvent(id='670', time=4.1484021187146185, real_time=2.480163570609616, value=34.5163536, curve_control1=None, curve_control2=None, prev_aligned_bpm=61.687793722222224), TempoAutomationFloatEvent(id='671', time=4.178364343989344, real_time=2.5093060217820256, value=95.9973831, curve_control1=None, curve_control2=None, prev_aligned_bpm=61.687793722222224), TempoAutomationFloatEvent(id='668', time=4.25, real_time=2.578981708028704, value=58.0627136, curve_control1=None, curve_control2=None, prev_aligned_bpm=61.687793722222224), TempoAutomationFloatEvent(id='672', time=4.457870775058275, real_time=2.7937881772788167, value=55.9149513, curve_control1=None, curve_control2=None, prev_aligned_bpm=58.0627136), TempoAutomationFloatEvent(id='712', time=4.548306901431902, real_time=2.8828996005984946, value=72.4000015, curve_control1=None, curve_control2=None, prev_aligned_bpm=63.594430905110116), TempoAutomationFloatEvent(id='700', time=4.80127970987346, real_time=3.113221253516874, value=78.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=76.86483333864655), TempoAutomationFloatEvent(id='600', time=5.0, real_time=3.268340530951092, value=50.3135643, curve_control1=None, curve_control2=None, prev_aligned_bpm=76.86483333864655), TempoAutomationFloatEvent(id='599', time=6.5, real_time=4.455212285145871, value=125.883995, curve_control1=None, curve_control2=None, prev_aligned_bpm=50.3135643), TempoAutomationFloatEvent(id='601', time=7.25, real_time=4.946994580622144, value=40.0667267, curve_control1=None, curve_control2=None, prev_aligned_bpm=125.883995), TempoAutomationFloatEvent(id='291', time=8.0, real_time=5.706896019728953, value=120.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=40.0667267), TempoAutomationFloatEvent(id='602', time=8.5, real_time=5.9305966531965275, value=183.949417, curve_control1=None, curve_control2=None, prev_aligned_bpm=120.0), TempoAutomationFloatEvent(id='603', time=9.5, real_time=6.410345802117857, value=54.1561279, curve_control1=None, curve_control2=None, prev_aligned_bpm=183.949417), TempoAutomationFloatEvent(id='596', time=12.0, real_time=7.860727189077446, value=200.0, curve_control1=None, curve_control2=None, prev_aligned_bpm=54.1561279), TempoAutomationFloatEvent(id='604', time=13.0, real_time=8.27541854608016, value=74.6498032, curve_control1=None, curve_control2=None, prev_aligned_bpm=200.0), TempoAutomationFloatEvent(id='605', time=15.25, real_time=9.587704231552863, value=147.658524, curve_control1=None, curve_control2=None, prev_aligned_bpm=74.6498032) ] assert proj.tempo_automation_events == auto assert proj.markers == [ Marker(time=0.0, text='A'), Marker(time=0.7452763515350631, text='X'), Marker(time=2.335821771598745, text='B'), Marker(time=4.173841066076857, text='D'), Marker(time=5.706896019728953, text='C'), Marker(time=6.905534691333889, text='Z'), Marker(time=7.692021891450212, text='1'), Marker(time=8.974199935476374, text='E'), Marker(time=10.705147339679828, text='YY') ]
def test_als_malform_no_ae(): fname = f'{TESTS_DIR_ALS}/markers-malformed-no-master-ae.als' with open(fname, 'rb') as f: proj = load_project(fname, f, theoretical=True) proj.parse()
def test_bad_ext(): with pytest.raises(UnknownExtension): load_project('f.mp3', BytesIO()) with pytest.raises(UnknownExtension): load_project('f', BytesIO())