Skip to content

Instantly share code, notes, and snippets.

@stephenhouser
Last active July 1, 2024 13:27
Show Gist options
  • Save stephenhouser/8644ab70473fdb565c2c0a6a862d705d to your computer and use it in GitHub Desktop.
Save stephenhouser/8644ab70473fdb565c2c0a6a862d705d to your computer and use it in GitHub Desktop.

Python OSC Example

Examples to send changing data to OSC receiver listening on UDP port 2222.

These examples are intended to be simple and easy to understand. They sacrifice perfection for ease of understanding.

There are four examples:

  • osc-random.py - sends random integers every second
  • osc-stocks.py - sends stock quotes every 15 seconds
  • osc-wav.py - plays a .wav file and sends the current sample (left and right channel)
  • osc-pyaudio.py - plays a .wav file and sends the current sample (left and right channel) -- NOT WORKING

Requirements

These examples use Python 3 and several additional Python packages. If you are using the command line and pip for package management, the following will install the prerequisites for you.

# for OSC communication with MAX/MSP
pip install python-osc

# for osc-stocks
pip install googlefinance

# for osc-wav
pip install sounddevice
pip install scipy

# pya.py
pip install pyaudio
pip install wave

Running the examples

The .wav file examples take the name of a .wav file as their single parameter.

python osc-wav.py science.wav
#!/usr/bin/env python3
"""
OSC/WAV Example: Play a wave file and send sound samples to OSC.
*** INCOMPLETE ***
This example plays a .wav file and sends the current left and
right channel sample data to an OSC receiver on UDP port 2222.
NOTE: This example uses PyAudio and it's callback to try
and synchronize the OSC messages with the currently playing
sound sample.
"""
import pyaudio
import wave
import time
import sys
# WAV file being played
wf = None
# Callback during playback
def callback(in_data, frame_count, time_info, status):
global wf
data = wf.readframes(frame_count)
print("{}".format(data))
return (data, pyaudio.paContinue)
def main():
global wf
wf = wave.open(sys.argv[1], 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
stream_callback=callback)
stream.start_stream()
while stream.is_active():
time.sleep(0.1)
stream.stop_stream()
stream.close()
wf.close()
p.terminate()
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
sys.exit(-1)
main()
#!/usr/bin/env python3
"""
OSC/Random Example: send random numbers to OSC.
This example sends a pseudo-random number between 0 and 1024
to the OSC receiver on UDP port 2222.
"""
from pythonosc import udp_client
from pythonosc import osc_message_builder
import time
import random
def main():
oscSender = udp_client.UDPClient("localhost", 2222)
while True:
n = random.randint(0, 1024)
print(n)
msg = osc_message_builder.OscMessageBuilder(address = "/rand")
msg.add_arg(n)
oscSender.send(msg.build())
time.sleep(1)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
OSC/Stocks Example: send stock market prices to OSC.
This example sends current stock market prices for a few
technology stocks to an OSC receiver on UDP port 2222.
"""
from pythonosc import udp_client
from pythonosc import osc_message_builder
from googlefinance import getQuotes
import json
import time
def main():
oscSender = udp_client.UDPClient("localhost", 2222)
while True:
quotes = getQuotes(['AAPL', 'GOGL'])
aapl = quotes[0]['LastTradePrice']
print("AAPL={}".format(aapl))
msg = osc_message_builder.OscMessageBuilder(address = "/AAPL")
msg.add_arg(float(aapl))
oscSender.send(msg.build())
gogl = quotes[1]['LastTradePrice']
print("GOGL={}".format(gogl))
msg = osc_message_builder.OscMessageBuilder(address = "/GOGL")
msg.add_arg(float(gogl))
oscSender.send(msg.build())
time.sleep(15)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
OSC/WAV Example: Play a wave file and send sound samples to OSC.
This example plays a .wav file and sends the current left and
right channel sample data to an OSC receiver on UDP port 2222.
NOTE: The sound samples are not perfectly timed with the
sound playback. This is, after all, just an example. The
synchronization is done based on elapsed time while the .wav
file is playing.
"""
import sys
from pythonosc import udp_client
from pythonosc import osc_message_builder
from scipy.io import wavfile
import sounddevice as sd
import json
import time
def show_info(aname, a):
print("Array", aname)
print("shape:", a.shape)
print("dtype:", a.dtype)
print("min, max:", a.min(), a.max())
print("")
def main():
oscSender = udp_client.UDPClient("localhost", 2222)
rate, data = wavfile.read(sys.argv[1])
show_info("data", data)
# Start playing the sound file
sd.play(data, rate)
start_time = time.time()
# Loop until we run out of time and samples
sample_nr = 0
while True:
# find the sample number that should be playing at the current time.
time_offset = time.time() - start_time
sample_nr = int(time_offset * rate)
# stop when we go past the last sample in the wav file
if sample_nr >= len(data):
break
# get the sample data for both left and right
(l, r) = data[sample_nr]
print("{:.3f} {:8d} ({:6d}, {:6d})".format(time_offset, sample_nr, l, r))
# send two messages to OSC, one for left and one for right
msg = osc_message_builder.OscMessageBuilder(address = "/left")
msg.add_arg(int(l))
oscSender.send(msg.build())
msg = osc_message_builder.OscMessageBuilder(address = "/right")
msg.add_arg(int(r))
oscSender.send(msg.build())
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Plays a wave file.\n\nUsage: {} filename.wav".format(sys.argv[0]))
sys.exit(-1)
main()
Python OSC Exampls to send changing data to OSC receiver listening on UDP port 2222.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment