Questo articolo vuole essere un esperimento del funzionamento del syntax highlighting del codice scritto con markdown, che pelican dovrebbe gestire in modo più o meno automatico.

Su debian stable attuale (bullseye) c'è una versione di pelican un po' vecchiotta, la 4.0.1 ma seguendo le istruzioni sulla relativa documentazione online dovrei esserci riuscito.

Per testare la cosa metto il codice di uno scriptino python che ho creato allo scopo di ottenere, dato un file audio o un bpm (beat per minute, lo standard musicale della velocità o tempo della musica) ritorna le durate dei vari tipi di note in millisecondi, e la frequenza in Hertz, utile per esempio per mettere a tempo un effetto delay e cose simili.

Ecco lo script:

#!/usr/bin/env python

import wave
from string import capwords
from optparse import OptionParser


def ms_to_bpm(length, measures=1.0, beat=1.0):
    """Calculates beat per minute of a soundfile given the lenght in
    milliseconds, the number of measures and the beat, where 4/4 is 1.
    Returns bpm
    """
    bpm = round(60000 / ((float(length / beat) / measures) / 4), 2)
    return bpm


def wavduration(wavfile: str) -> int:
    """Returns the duration of a wavfile in milliseconds"""
    myfile = wave.open(wavfile, "r")
    frames = 1.0 * myfile.getnframes()
    sr = myfile.getframerate()
    time = 1.0 * (frames / sr)
    return int(round(time * 1000))


def delay_times(bpm=120.0):
    """Returns delay times for the specified bpm, in milliseconds"""
    result = []
    durations = [
        (1, "whole"),
        ((3.0 / 4), "dotted half"),
        ((1.0 / 2), "half"),
        ((3.0 / 8), "dotted quarter"),
        ((1.0 / 4), "quarter"),
        ((3.0 / 16), "dotted eight"),
        (round(((1.0 / 2) / 3), 5), "quarter triplet"),
        ((1.0 / 8), "eight"),
        ((3.0 / 32), "dotted sixteenth"),
        (round(((1.0 / 4) / 3), 5), "eight triplet"),
        ((1.0 / 16), "sixteenth"),
        ((3.0 / 64), "dotted thirty second"),
        (round(((1.0 / 8) / 3), 5), "sixteenth triplet"),
        ((1.0 / 32), "thirty second"),
    ]
    for duration, description in durations:
        title = capwords(description)
        delay = (duration * 4000) / (bpm / 60.0)
        frequency = 1000 / delay
        result.append(
            {
                "title": title,
                "delay": delay,
                "frequency": frequency,
            }
        )
    return result


def delay_times_format(bpm=120.0):
    result = delay_times(bpm)
    print(f"\n {bpm} beats per minute (bpm):")
    print()
    print("Note                  Delay time             LFO freq")
    print(55 * "-")
    for line in result:
        title = line["title"].ljust(20, " ")
        delay = round(line["delay"], 3)
        frequency = round(line["frequency"], 2)
        print(
            title,
            delay.__str__().rjust(8),
            "ms ",
            10 * " ",
            frequency.__str__().rjust(5),
            "Hz",
        )


if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option(
        "-f",
        "--file",
        dest="filename",
        default="none",
        help="wave FILE to load",
        metavar="FILE",
    )
    parser.add_option(
        "-b",
        "--bpm",
        dest="bpm",
        default="analize",
        help="beats per minute",
    )
    parser.add_option(
        "-B",
        "--bars",
        dest="bars",
        help="number of bars in the wav file",
    )
    parser.add_option(
        "-m",
        "--meter",
        dest="meter",
        help="as in 3/4 or 12/8, default 4/4",
    )

    (options, args) = parser.parse_args()


    if options.meter:
        a = options.meter.split("/")
        meter = float(a[0]) / float(a[1])
        print("\nMeter is", options.meter)
    else:
        meter = 1
        print("\nMeter is 4/4")

    if options.bars:
        bars = int(options.bars)
    else:
        bars = 1
    wavfile = options.filename

    if wavfile == "none":
        print("No files to analize, defaulting to bpm provided, or 120")
        if options.bpm == "analize":
            bpm = 120
        else:
            bpm = float(options.bpm)
    else:

        if options.bpm != "analize":
            bpm = float(options.bpm)
            delay_times_format(bpm)
        else:
            bpm = 120

        print(75 * "-", "\n")

        wavdur = wavduration(wavfile)
        print(wavfile, "is", wavdur, "milliseconds")
        bpm = ms_to_bpm(wavdur, bars, meter)

        # bpm = ms_to_bpm(3850,2,1)
        print("Bpm of", wavfile, "is", bpm)

    delay_times_format(bpm)