parse static method

FaustSequencer parse(
  1. String input
)

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;
}