Added music21 and csound examples
This commit is contained in:
@ -7,12 +7,67 @@ try:
|
||||
except ImportError:
|
||||
music21_imported: bool = False
|
||||
|
||||
try:
|
||||
import ctcsound
|
||||
csound_imported: bool = True
|
||||
except (ImportError, TypeError) as Error:
|
||||
csound_imported: bool = False
|
||||
|
||||
def freq_to_pch(freq: float) -> str:
|
||||
"Format frequency to Csound PCH format"
|
||||
return f"{freq:.2f}"
|
||||
|
||||
# Csound score example: i1 0 1 0.5 8.00
|
||||
# 1. The first number is the instrument number. In this case it is instrument 1.
|
||||
# 2. The second number is the start time in seconds. In this case it is 0 seconds.
|
||||
# 3. The third number is the duration in seconds. In this case it is 1 second.
|
||||
# 4. The fourth number is the amplitude. In this case it is 0.5.
|
||||
# 5. The fifth number is the frequency. In this case it is 8 Hz.
|
||||
|
||||
def freqs_and_durations_to_csound_score(pairs: list[list[float|list[float], float|list[float]]], bpm: int=80, amp: float=0.5, instr: (int|str)=1) -> str:
|
||||
"""Tranforms list of lists containing frequencies and note lengths to csound score format.
|
||||
Note lengths are transformed in seconds with the bpm.
|
||||
Start time in seconds is calculated and summed from the note lengths.
|
||||
If frequency is None, then it is a rest.
|
||||
If frequency is a list, then it is a chord.
|
||||
|
||||
Example input: [[261.6255653005986, 0.5], [None, 0.25], [440.0, 0.125], [[261.6255653005986, 329.62755691286986, 391.9954359817492], [0.25, 0.125, 0.25]]]"""
|
||||
score = ""
|
||||
instr = f'"{instr}"' if isinstance(instr, str) else instr
|
||||
start_time = 0
|
||||
for pair in pairs:
|
||||
if isinstance(pair[0], list):
|
||||
for freq, dur in zip(pair[0], pair[1]):
|
||||
score += f"i {instr} {start_time} {dur * 4 * 60 / bpm} {amp} {freq_to_pch(freq)}\n"
|
||||
start_time += max(pair[1]) * 4 * 60 / bpm
|
||||
else:
|
||||
if pair[0] is None:
|
||||
score += f"i {instr} {start_time} {pair[1] * 4 * 60 / bpm} {amp} 0\n"
|
||||
else:
|
||||
score += f"i {instr} {start_time} {pair[1] * 4 * 60 / bpm} {amp} {freq_to_pch(pair[0])}\n"
|
||||
start_time += pair[1] * 4 * 60 / bpm
|
||||
return score
|
||||
|
||||
def to_csound_score(expression: str | Ziffers, bpm: int=80, amp: float=0.5, instr: (int|str)=1) -> str:
|
||||
""" Transform Ziffers object to Csound score """
|
||||
if not csound_imported:
|
||||
raise ImportError("Install Csound library")
|
||||
|
||||
if isinstance(expression, Ziffers):
|
||||
score = freqs_and_durations_to_csound_score(expression.freq_pairs(),bpm,amp,instr)
|
||||
else:
|
||||
parsed = zparse(expression)
|
||||
score = freqs_and_durations_to_csound_score(parsed.freq_pairs(),bpm,amp,instr)
|
||||
|
||||
return score
|
||||
|
||||
def to_music21(expression: str | Ziffers, **options):
|
||||
"""Helper for passing options to the parser"""
|
||||
|
||||
if not music21_imported:
|
||||
raise ImportError("Install Music21 library")
|
||||
|
||||
# Register the ZiffersMusic21 converter
|
||||
converter.registerSubconverter(ZiffersMusic21)
|
||||
|
||||
if isinstance(expression, Ziffers):
|
||||
|
||||
Reference in New Issue
Block a user