commit df878ebab26ca805ccc319164f8bc9f266bc2bcc Author: Francesco Luzzana Date: Mon Dec 26 16:35:33 2022 +0100 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bc348e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +venv/ +__pycache__ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e299f38 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Seq + +![cover made with libre office calc](cover.png) + +An open ended CSV sequencer. It only takes care of looping through a .csv file, row by row, and send the contents of each one to a client with OSC. + +In this way all the command logic is up to the user, and the sequencer can be prototyped on the go. + +There is no restriction in the number or lenght of columns. + +Tested with a VVVV client with different modes: + +- frequency + `440` + enter the frequency for a basic oscillator + +- frequency + waveform + `s400`, `t600`, `n700` + first character is the waveform (sine, tri, noise, pulse), the rest is the frequency + +- midi + `m064`, `m148` + m stands for midi, first digit is the midi channel, the rest is the note + ![](2022-12-26-16-26-40.png) + +## Install + +To install create a virtual environemnt and then install the requirements from the `requirements.txt` file. + +`python3 -m venv venv` + +`source venv/bin/activate` + +`pip install -r requirements.txt` + +## Run + +To run the sequencer run + +`python seq.py` + +It will read the contents of the `seq.csv` file and forward them on a OSC client running on the local ip `127.0.0.1`, on the port `1337` + +Note that you can edit live the `seq.csv` file with a software like LibreOffice Calc, or directly as a text file. + +ATM the main loop of the sequencer reload the file at every step. Not really efficient! But for small files should not be a problem. + +## Next steps + +- Use env files to set ports and osc address +- bpm as command line arguments diff --git a/Seq.vl b/Seq.vl new file mode 100644 index 0000000..8dbbdcf --- /dev/null +++ b/Seq.vl @@ -0,0 +1,1006 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toggle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s + t + n + r + m + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toggle + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + High + + + + + + + + + + + High + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cover.png b/cover.png new file mode 100644 index 0000000..053224e Binary files /dev/null and b/cover.png differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a065ec5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +python-osc==1.8.0 diff --git a/seq.csv b/seq.csv new file mode 100644 index 0000000..f7bc011 --- /dev/null +++ b/seq.csv @@ -0,0 +1,7 @@ +Track 1,Track 2,Track 3,Track 4 +m064\0.1,,, +,,, +m098,,, +,,, +,,, +M064\2,,, diff --git a/seq.py b/seq.py new file mode 100644 index 0000000..e4a3363 --- /dev/null +++ b/seq.py @@ -0,0 +1,42 @@ +import csv +import time +from pythonosc.udp_client import SimpleUDPClient + +class Loop: + + index = 0 + + def __init__(self, seq: list, bpm: int, ip="127.0.0.1", port=1337): + self.seq = seq + self.bpm = bpm + self.client = SimpleUDPClient(ip, port) + + def read(self): + with open('seq.csv', newline='') as f: + self.seq = [step for step in csv.DictReader(f)] + + + def process(self, step): + commands = [command for command in step.values()] + self.client.send_message('/seq', commands) + for key, value in step.items(): + print(value, end=' ') + print('') + + def main(self): + while True: + self.read() + try: + self.process(self.seq[self.index]) + except IndexError: + self.index = 0 + self.process(self.seq[self.index]) + self.index = self.index + 1 if self.index < len(self.seq) - 1 else 0 + time.sleep(60/self.bpm/4) + + +if __name__ == "__main__": + with open('seq.csv', newline='') as f: + sequence = [step for step in csv.DictReader(f)] + loop = Loop(sequence, 120) + loop.main() \ No newline at end of file