diff --git a/README.md b/README.md index dd9d4b5..d9564c5 100644 --- a/README.md +++ b/README.md @@ -2,40 +2,62 @@ ## Multitrack exporter --- -## Despription +## Description -- Exports Patterns and projects individual Audio Tracks to seperate folders for use in your DAW -- Python cross plattform with single file binary for x86 linux +- Exports patterns and projects individual audio tracks to seperate folders for use in your DAW. +- Python cross plattform with single file binary for x86 linux. -## Installation -### Ubuntu 20.10 LTS (If the binary in /dist doesn't work) - -`sudo apt install portaudio19-dev` -`sudo apt install python3-tk` -`pip install python-rtmidi` -`pip install pyaudio` - -### Mac Install - -`brew install portaudio` -`brew install python-tk` -`pip install python-rtmidi` -`pip install pyaudio` -`pip install mido` - -`python3 underbridge.py` to start - -### Linux binary +## Using Packaged single file Binarys _(The easy way)_ +- Executables reside in the folder `/dist/` +- on Windows + `underbridge.exe` +- On Linux: ``./underbridge`` -Underbridge_alt was packaged on a different system. Might help if you run into problems. + +Underbridge_alt was packaged on a different system. Might help if you run into problems. (Outdated) + +## Installation _(Less easy way)_ + +### Windows + +- Install Python 3.9 if not already, 3.10 seems to cause problems. +- install portaudio_dev : `apt install portaudio19-dev` +- install mido : `pip install mido` +- install rt-midi: `pip isntall rt-midi` +- install pipwin: `pip install pipwin` +- install pyaudio `pipwin install pyaudio` + +**Activate OP-Z device input in sound settings of windows and make it default** + +- run `python underbridge.py` + +### Mac Install - ( tested on Mac OS Monterey 12.3 ) + +install portaudio: `brew install portaudio` +install mido: `pip install mido` +install tk: `brew install python-tk` +install rt-midi: `pip install python-rtmidi` +install pyaudio: `pip install pyaudio` + +**Set OP-Z device as input in sound of system preferences** + +open terminal and type: `python3 underbridge.py` to start + +### Ubuntu 20.10 LTS + + - `sudo apt install portaudio19-dev` +- `sudo apt install python3-tk` +- `pip install python-rtmidi` +- `pip install pyaudio` + +`python3 underbridge.py` to start ## Steps - connect OP-Z via USB -- in /dist/ directory run ``./underbridge`` -- Alternatively python3 underbridge.py in root directory. Make sure you have installed dependencies before.. +- Run underbridge ### Single Pattern Mode @@ -53,7 +75,7 @@ Underbridge_alt was packaged on a different system. Might help if you run into p - Select Porject and first Pattern you want to export on OP-Z. - Enter name for the project. This is used for the folder structure - Get BPM from led code or Smartphone app. -- Enter BPM +- Enter BPM - Enter longest Bar of you track (1-4) - Enter the Nr. of Patterns your song consists of. - Optionally enter additional seconds at the end of the recording to capture reverb tails etc. @@ -61,7 +83,5 @@ Underbridge_alt was packaged on a different system. Might help if you run into p - Select directory you want to record the waves to - Click record and wait until finished. - - - - +### Troubleshooting +- When the recorded audio contains buzzing or other artifacts try disabling the USB charging with "display" and "bottom right key" to disable. diff --git a/dist/underbridge b/dist/underbridge index 2906548..7a18685 100755 Binary files a/dist/underbridge and b/dist/underbridge differ diff --git a/dist/underbridge.exe b/dist/underbridge.exe new file mode 100644 index 0000000..23988b4 Binary files /dev/null and b/dist/underbridge.exe differ diff --git a/import pyaudio.py b/import pyaudio.py new file mode 100644 index 0000000..2ace049 --- /dev/null +++ b/import pyaudio.py @@ -0,0 +1,7 @@ +import pyaudio +p = pyaudio.PyAudio() +info = p.get_host_api_info_by_index(0) +numdevices = info.get('deviceCount') +for i in range(0, numdevices): + if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0: + print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name')) \ No newline at end of file diff --git a/underbridge.py b/underbridge.py index 5a80bc1..1cf38de 100644 --- a/underbridge.py +++ b/underbridge.py @@ -1,7 +1,6 @@ # Underbridge OP-Z multichannel exporter # Copyright 2022 Thomas Herrmann Email: herrmann@raise-uav.com - import mido import pyaudio import wave @@ -11,6 +10,9 @@ import time import threading import os +device_list = [] +op_device = [] +audio_device = [] loop_time = 0 inport = 0 outport = 0 @@ -25,11 +27,39 @@ cancel = 0 def getMIDIDevice(): - pass + global device_list + global op_device + device_list = mido.get_output_names() + print (device_list) + try: + op_device = list(filter(lambda x: 'OP-Z' in x, device_list)) + op_device = op_device[0] + print (op_device) + displaymsg.set("OP-Z found") + except: + displaymsg.set("CanĀ“t find OP-Z : MIDI Error.") +def getAudioDevice(): + global audio_device + p = pyaudio.PyAudio() + try: + info = p.get_host_api_info_by_index(0) + numdevices = info.get('deviceCount') + for i in range(0, numdevices): + if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0: + print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name')) + for i in range(0, numdevices): + #audio_device = p.get_device_info_by_host_api_device_index(0, i).get('name') + if "OP-Z" in p.get_device_info_by_host_api_device_index(0, i).get('name') and (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0: + audio_device = i + + print ("Detected OP-Z audio at Index:",audio_device, p.get_device_info_by_host_api_device_index(0, audio_device).get('name')) + except: + displaymsg.set("OP-Z Audio Device not found.") def getBPM(): - inport= mido.open_input('OP-Z:OP-Z MIDI 1 20:0') + global op_device + inport= mido.open_input(op_device) msg = inport.poll() #print(msg) @@ -55,8 +85,9 @@ def setParam(): def openMidi(): global outport - outport= mido.open_output('OP-Z:OP-Z MIDI 1 20:0') - displaymsg.set("OP-Z MIDI not connected :(") + global op_device + outport= mido.open_output(op_device) + #displaymsg.set("OP-Z MIDI not connected :(") print(outport) def setProject(projnr): @@ -102,8 +133,10 @@ def nextPattern(): def nextSong(): pass -def closeMidi(): - pass +def closeMidi(): + global outport + outport.close() + displaymsg.set("MIDI closed") def setPath(): global path @@ -139,26 +172,29 @@ def start_Rec(): global j global pro global pattern_nr - CHUNK = 1024 + global audio_device + + CHUNK = 128 FORMAT = pyaudio.paInt16 CHANNELS = 2 - RATE = 44100 + RATE = 48000 RECORD_SECONDS = loop_time WAVE_OUTPUT_FILENAME = name_input.get()+ "_" + "track" + str(j+1) + ".wav" - p = pyaudio.PyAudio() - start_MIDI() + p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, + input_device_index= audio_device, frames_per_buffer=CHUNK + ) #print("* recording") frames = [] - + start_MIDI() for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) @@ -184,12 +220,19 @@ def start_Rec(): displaymsg.set("End of Recording") def sequenceMaster(): + global cancel global pattern_nr cancel = 0 #print("test") + + getMIDIDevice() + time.sleep(1) + getAudioDevice() + displaymsg.set("Sequence started") - try: + + try: openMidi() if mode_select.get() == 2: @@ -201,11 +244,13 @@ def sequenceMaster(): break #print("sequence started",i) muteAll() + time.sleep(0.1) setSolo(i) #starting Midi during wave record for timing start_Rec() #print(i) stop_MIDI() + time.sleep(1) unmuteAll() mode = mode_select.get() @@ -218,13 +263,15 @@ def sequenceMaster(): pattern_nr = 0 sequenceMaster() except: - displaymsg.set("OP-Z connection Problem :(") + displaymsg.set("OP-Z Sequence error try restarting the OP-Z or press CANCEL Button") def cancelRec(): global cancel + global outport global j j = 0 cancel = 1 + closeMidi() #GUI Main buttonsize_x = 7