[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]