parse static method
Implementation
static FaustSequencer parse(String input) {
final lines = input.trim().split('\n');
double baseFreq = 261.63;
double bpm = 120.0;
int grid = 4;
String rawPattern = "";
final Map<int, double> instrumentBaseFreqs = {};
final Map<int, double> instrumentGains = {};
for (var line in lines) {
if (line.contains(':')) {
final parts = line.split(':');
final key = parts[0].trim().toLowerCase();
final valSection = parts[1].trim();
final int? instId = int.tryParse(key);
if (instId != null) {
// Parse "Freq (gain=X)"
final freqMatch = RegExp(r'^([\d.]+)(?:\s*\(gain=([\d.]+)\))?').firstMatch(valSection);
if (freqMatch != null) {
instrumentBaseFreqs[instId] = double.tryParse(freqMatch.group(1)!) ?? 0.0;
if (freqMatch.group(2) != null) {
instrumentGains[instId] = double.tryParse(freqMatch.group(2)!) ?? 1.0;
}
}
} else if (key == 'basefreq') {
baseFreq = double.tryParse(valSection) ?? baseFreq;
} else if (key == 'bpm') {
bpm = double.tryParse(valSection) ?? bpm;
} else if (key == 'grid') {
grid = int.tryParse(valSection) ?? grid;
}
} else {
rawPattern += line.trim();
}
}
instrumentBaseFreqs.putIfAbsent(1, () => baseFreq / 2.0);
instrumentBaseFreqs.putIfAbsent(0, () => baseFreq);
final sequencer = FaustSequencer(tempoBpm: bpm);
final double stepDur = 1.0 / grid;
final tokenRegex = RegExp(r'(\d+)(?:\(([^)]+)\)|([a-zA-Z12]+))|([._^])');
final matches = tokenRegex.allMatches(rawPattern).toList();
final Map<int, double> lastFreq = {};
for (int i = 0; i < matches.length; i++) {
final match = matches[i];
final double currentBeat = i * stepDur;
if (match.group(4) != null) continue;
final int instId = int.parse(match.group(1)!);
final String expr = (match.group(2) ?? match.group(3) ?? "Sa");
final double instBase = instrumentBaseFreqs[instId] ?? baseFreq;
final double instGain = instrumentGains[instId] ?? 1.0;
double ratio = _evaluateExpression(expr);
final double freq = instBase * ratio;
double duration = stepDur;
int lookAhead = i + 1;
while (lookAhead < matches.length && matches[lookAhead].group(4) == '.') {
duration += stepDur;
lookAhead++;
}
if (i > 0 && matches[i-1].group(4) == '^' && lastFreq.containsKey(instId)) {
_generateMeend(sequencer, instId, lastFreq[instId]!, freq, currentBeat - stepDur, stepDur, instGain);
}
sequencer.addNote(
instrumentId: instId, pitch: freq, beat: currentBeat,
duration: duration * 0.95, velocity: 0.8 * instGain,
legato: lookAhead < matches.length && matches[lookAhead].group(4) == '^',
);
lastFreq[instId] = freq;
}
return sequencer;
}