diff --git a/src/notochord/__main__.py b/src/notochord/__main__.py index 7a4bd9a..81d04f3 100644 --- a/src/notochord/__main__.py +++ b/src/notochord/__main__.py @@ -12,6 +12,7 @@ def help(): homunculus: run the Notochord homunculus TUI harmonizer: run the Notochord harmonizer TUI improviser: run the Notochord improviser TUI + txalaparta: run the txalaparta app files: show the location of Notochord models and config files on disk """) @@ -30,6 +31,9 @@ def _main(): if sys.argv[1] == 'improviser': sys.argv = sys.argv[1:] run(improviser) + if sys.argv[1] == 'txalaparta': + sys.argv = sys.argv[1:] + run(txalaparta) if sys.argv[1] == 'files': d = Notochord.user_data_dir() print(d) diff --git a/src/notochord/app/__init__.py b/src/notochord/app/__init__.py index 7247518..f542652 100644 --- a/src/notochord/app/__init__.py +++ b/src/notochord/app/__init__.py @@ -1,4 +1,5 @@ from .server import main as server from .harmonizer import main as harmonizer from .improviser import main as improviser -from .homunculus import main as homunculus \ No newline at end of file +from .homunculus import main as homunculus +from .txalaparta import main as txalaparta \ No newline at end of file diff --git a/src/notochord/app/improviser-txala.py b/src/notochord/app/txalaparta.py similarity index 96% rename from src/notochord/app/improviser-txala.py rename to src/notochord/app/txalaparta.py index 2a17cce..49ee9da 100644 --- a/src/notochord/app/improviser-txala.py +++ b/src/notochord/app/txalaparta.py @@ -17,10 +17,10 @@ from rich.panel import Panel from rich.pretty import Pretty from textual.reactive import reactive -from textual.widgets import Header, Footer, Static, Button, TextLog +from textual.widgets import Header, Footer, Static, Button, Log ### def TUI components ### -class NotoLog(TextLog): +class NotoLog(Log): value = reactive('') def watch_value(self, time: float) -> None: self.write(self.value) @@ -60,7 +60,7 @@ def compose(self): ### end def TUI components### def main( - checkpoint="artifacts/noto-txala-011-0020.ckpt", # Notochord checkpoint + checkpoint="txala-latest.ckpt", # Notochord checkpoint player_config:Dict[int,int]=None, # map MIDI channel : GM instrument noto_config:Dict[int,int]=None, # map MIDI channel : GM instrument pitch_set=(41,43,45), # MIDI pitches used @@ -97,7 +97,8 @@ def main( use_tui=True, # run textual UI predict_player=True, # forecasted next events can be for player (preserves model distribution, but can lead to Notochord deciding not to play) auto_query=True, # query notochord whenever it is unmuted and there is no pending event. generally should be True except for testing purposes. - testing=False + testing=False, + verbose=0 ): """ Args: @@ -252,7 +253,8 @@ def play_event(event, channel, feed=True, send=True, tag=None, memo=None): state['run_length'] = 1 state['last_side'] = side - print(f'{state["run_length"]=}') + if verbose > 0: + print(f'{state["run_length"]=}') # send out as MIDI if send: @@ -309,8 +311,9 @@ def noto_query(delay=0): # print(counts) player_count = sum(counts[i] for i in player_map.insts) noto_count = sum(counts[i] for i in noto_map.insts) - print(f'player: {player_count}') - print(f'noto: {noto_count}') + if verbose > 0: + print(f'player: {player_count}') + print(f'noto: {noto_count}') total_count = player_count + noto_count all_insts = noto_map.insts @@ -320,7 +323,8 @@ def noto_query(delay=0): steer_time = 1-controls.get('steer_rate', 0.5) tqt = (max(0,steer_time-0.5), min(1, steer_time+0.5)) - print(tqt) + if verbose > 1: + print(tqt) # if using nominal time, # *subtract* estimated feed latency to min_time; (TODO: really should @@ -346,7 +350,8 @@ def noto_query(delay=0): if len(insts)==0: insts = all_insts - print(f'{insts=}') + if verbose > 1: + print(f'{insts=}') # bal_insts = set(counts.index[counts <= counts.min()+n_margin]) # if balance_sample and len(bal_insts)>0: @@ -371,7 +376,8 @@ def noto_query(delay=0): max_t = None if max_time is None else max(max_time, min_time+0.2) - print(min_time, max_t) + if verbose > 1: + print(min_time, max_t) pending.event = query_method( include_pitch=pitch_set, @@ -419,7 +425,8 @@ def _(msg): # print(f"{controls['steer_density']=}") if msg.control==3: controls['steer_rate'] = msg.value/127 - print(f"{controls['steer_rate']=}") + if verbose > 0: + print(f"{controls['steer_rate']=}") if msg.control==4: noto_reset() diff --git a/src/notochord/model.py b/src/notochord/model.py index 483d601..5db0954 100644 --- a/src/notochord/model.py +++ b/src/notochord/model.py @@ -1207,6 +1207,13 @@ def from_checkpoint(cls, path): path: file path to Notochord model """ if path=="notochord-latest.ckpt": + url = 'https://github.com/Intelligent-Instruments-Lab/iil-python-tools/releases/download/notochord-v0.4.0/notochord_lakh_50G_deep.pt' + elif path=="txala-latest.ckpt": + url = 'https://github.com/Intelligent-Instruments-Lab/notochord/releases/download/notochord-v0.5.4/noto-txala-011-0020.ckpt' + else: + url = None + + if url is not None: d = Notochord.user_data_dir() path = d / path # maybe download @@ -1214,12 +1221,12 @@ def from_checkpoint(cls, path): while True: answer = input("Do you want to download a notochord model? (y/n)") if answer.lower() in ["y","yes"]: - download_url('https://github.com/Intelligent-Instruments-Lab/iil-python-tools/releases/download/notochord-v0.4.0/notochord_lakh_50G_deep.pt', path) + download_url(url, path) print(f'saved to {path}') break if answer.lower() in ["n","no"]: break - # path = + # path = checkpoint = torch.load(path, map_location=torch.device('cpu')) model = cls(**checkpoint['kw']['model']) model.load_state_dict(checkpoint['model_state'], strict=False)