[LAD] Re: Python audio-metronome + MIDI question
"Jeanette C." <julien-3g/[email protected]> Thu, 12 Dec 2024 21:47:14 +0100 (CET)
| Newsgroups | gmane.linux.audio.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello Fons,
many thanks for the suggestions and your code. Taking all that into account I
agree with your assessment and leave the metronome in MIDI, though I will keep
the modified code around.
Btw. it was Python's prompt_toolkit library that made me turn from good old
c++ to Python. From all the examples I've seen it is a fantastic library for
shell/fullscreen terminal UIs. And possibly a few minor solutions I did in
Python. It is enticing to use it. :)
Best wishes and many thanks once again for valuable code and advice,
Jeanette
Dec 12 2024, Fons Adriaensen has written:
> On Wed, Dec 11, 2024 at 11:42:57AM +0100, Jeanette C. wrote:
>
>> Is there a better, hopefully simple, way to play these clicks?
>
> If you're building a sequencer anyway, just output the metronome
> clicks as one additional track. i.e. just a repeating sequence
> of note on/off events to be rendered by a synth.
>
> Or you could use the JackSignal class from zita-jacktools
> to play the ticks. Giant overkill but it will work.
>
> JackSignal allows to play and/or capture Jack audio from/to numpy
> buffers. It's meant to do automated audio measurements with all
> signals generated and/or analysed in Python.
>
> The example below receives MIDI clock (using the Aseqmidi class)
> and outputs a tick every quarter note. In this case the two tick
> sounds are generated in Python, but you could as well input them
> from files (using zita-audiotools).
>
> When S.process () is called, output will start at the next Jack
> period boundary, so with -p 256 you'd have +/- 2.7 ms jitter.
>
> Note that if the metronome is a separate program (like the one
> below), it also needs to handle song position messages to be in
> sync with the sequencer.
>
>
> #!/usr/bin/python
>
> from zita_alsamidi.aseqmidi import *
> from zita_jacktools.jacksignal import *
> from time import sleep
> from math import pi, sin
> import numpy as np
>
>
> # Play sound
> #
> def playsound ():
> global K # Beat counter
> if S.get_state () != JackSignal.SILENCE:
> return # Still playing previous one...
> # Enable one of the two waveforms.
> if K == 0:
> S.set_output_gain (0, 1.0)
> S.set_output_gain (1, 0.0)
> else:
> S.set_output_gain (0, 0.0)
> S.set_output_gain (1, 1.0)
> # Start playback.
> S.process ()
> # Handle 4/4 signature.
> K += 1
> if K == 4: K = 0
>
>
> # Midi message handler
> #
> def handler (args):
> global C # Clock counter
> if args [1][0] == 36: # 36 = SND_SEQ_EVENT_CLOCK
> C += 1
> if C == 24:
> playsound ()
> C = 0
>
>
> # Generate a 'ping' waveform.
> #
> def genping (freq, rate, size):
> D = np.zeros ((size,), dtype = np.float32)
> w = 2 * pi * freq / rate
> a = 0.3
> m = pow (0.01, 1.0 / size)
> for i in range (size):
> D [i] = a * sin (i * w)
> a *= m
> return D
>
>
> S = JackSignal ("Metronome")
> if S.get_state () < 0:
> print ("Can't create JackSignal")
> exit (1)
>
> name, rate, frag = S.get_jack_info ()
> # Should be short enough so they don't overlap.
> size = int (0.15 * rate)
> D1 = genping (880, rate, size)
> D2 = genping (440, rate, size)
>
> S.create_output (0, 'out-1')
> S.create_output (1, 'out-2')
> S.silence ()
> # Connect Jack outputs...
> # S.connect_output (0, '...')
> # S.connect_output (1, '...')
> S.set_output_data (0, D1)
> S.set_output_data (1, D2)
>
>
> C = 0 # Clock message counter.
> K = 0 # Beat counter
> M = Aseqmidi ("Metronome", handler)
> sleep (10000)
>
>
> --
> FA
>
>
> _______________________________________________
> Linux-audio-dev mailing list -- linux-audio-dev-cunTk1MwBs/[email protected]
> To unsubscribe send an email to linux-audio-dev-leave-cunTk1MwBs/[email protected]
>
--
* Website: http://juliencoder.de - for summer is a state of sound
* Youtube: https://www.youtube.com/channel/UCMS4rfGrTwz8W7jhC1Jnv7g
* Audiobombs: https://www.audiobombs.com/users/jeanette_c
* GitHub: https://github.com/jeanette-c
I used to think
I had the answers to everything
But now I know
... :) <3
(Britney Spears)
_______________________________________________
Linux-audio-dev mailing list -- linux-audio-dev-cunTk1MwBs/[email protected]
To unsubscribe send an email to linux-audio-dev-leave-cunTk1MwBs/[email protected]