Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for python-rtmidi #62

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Website: [www.samplerbox.org](https://www.samplerbox.org)

# Install

SamplerBox works with the RaspberryPi's built-in soundcard, but it is recommended to use a USB DAC (PCM2704 USB DAC for less than 10€ on eBay is fine) for better sound quality.
SamplerBox works with the RaspberryPi's built-in soundcard, but it is recommended to use a USB DAC (PCM2704 USB DAC for less than 10€ on eBay is fine) for better sound quality.

You can use a ready-to-use ISO image from the [Releases](https://github.com/josephernest/SamplerBox/releases) page or do a manual install:

Expand All @@ -22,28 +22,38 @@ You can use a ready-to-use ISO image from the [Releases](https://github.com/jose

~~~
sudo apt update
sudo apt -y install git python3-pip python3-smbus python3-numpy libportaudio2
sudo apt -y install git python3-pip python3-smbus python3-numpy libportaudio2 libasound2-dev
sudo apt -y install raspberrypi-kernel # quite long to install, do it only if necessary, it solves a "no sound before 25 second on boot" problem
sudo pip3 install cython rtmidi-python cffi sounddevice pyserial
sudo pip3 install cython cffi sounddevice pyserial
~~~

2. Download SamplerBox and build it with:

For python < 3.9
~~~
sudo pip3 install rtmidi-python
~~~

For python >= 3.9
~~~
sudo pip3 install python-rtmidi
~~~

1. Download SamplerBox and build it with:
dosas marked this conversation as resolved.
Show resolved Hide resolved

~~~
git clone https://github.com/josephernest/SamplerBox.git
cd SamplerBox
sudo python3 setup.py build_ext --inplace
~~~

3. Reboot the Pi, and run the soft with:
1. Reboot the Pi, and run the soft with:

~~~
sudo python3 samplerbox.py
~~~

Play some notes on the connected MIDI keyboard, you'll hear some sound!

4. *(Optional)* Modify `config.py` if you want to change root directory for sample-sets, default soundcard, etc.
1. *(Optional)* Modify `config.py` if you want to change root directory for sample-sets, default soundcard, etc.


# How to use it
Expand Down
55 changes: 42 additions & 13 deletions samplerbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
import threading
from chunk import Chunk
import struct
import rtmidi_python as rtmidi
try:
import rtmidi_python as rtmidi
RTMIDI = False
except ModuleNotFoundError:
import rtmidi
RTMIDI = True
import samplerbox_audio

#########################################
Expand Down Expand Up @@ -165,7 +170,18 @@ def AudioCallback(outdata, frame_count, time_info, status):
b *= globalvolume
outdata[:] = b.reshape(outdata.shape)

def MidiCallback(message, time_stamp):

def midi_callback(message, data=None):
message, deltatime = message

return midi_callback_common(message, None)


def MidiCallback(message, timestamp):
return midi_callback_common(message, timestamp)


def midi_callback_common(message, timestamp):
global playingnotes, sustain, sustainplayingnotes
global preset
messagetype = message[0] >> 4
Expand Down Expand Up @@ -424,14 +440,27 @@ def MidiSerialCallback():
# MAIN LOOP
#########################################

midi_in = [rtmidi.MidiIn(b'in')]
previous = []
while True:
for port in midi_in[0].ports:
if port not in previous and b'Midi Through' not in port:
midi_in.append(rtmidi.MidiIn(b'in'))
midi_in[-1].callback = MidiCallback
midi_in[-1].open_port(port)
print('Opened MIDI: ' + str(port))
previous = midi_in[0].ports
time.sleep(2)
if RTMIDI:
midi_in = [rtmidi.MidiIn()]
previous = []
while True:
for num_port, port in enumerate(midi_in[0].get_ports()):
if port not in previous and 'Midi Through' not in port:
midi_in.append(rtmidi.MidiIn())
midi_in[-1].set_callback(midi_callback)
midi_in[-1].open_port(num_port)
print('Opened MIDI: ' + str(port))
previous = midi_in[0].get_ports()
time.sleep(2)
else:
midi_in = [rtmidi.MidiIn(b'in')]
previous = []
while True:
for port in midi_in[0].ports:
if port not in previous and b'Midi Through' not in port:
midi_in.append(rtmidi.MidiIn(b'in'))
midi_in[-1].callback = MidiCallback
midi_in[-1].open_port(port)
print('Opened MIDI: ' + str(port))
previous = midi_in[0].ports
time.sleep(2)