/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <string.h>
#include <errno.h>

#include "prefs.h"
#include "log.h"
#include "midi.h"
#include "notes.h"

char *opt_midiDevice;

struct NoteDeviceStruct {
  MidiDevice *midi;
  int channelNumber;
};

static NoteDevice *
midiConstruct (int errorLevel) {
  NoteDevice *device;

  if ((device = malloc(sizeof(*device)))) {
    if ((device->midi = openMidiDevice(errorLevel, opt_midiDevice))) {
      device->channelNumber = 0;
      setMidiInstrument(device->midi, device->channelNumber, prefs.midiInstrument);

      logMessage(LOG_DEBUG, "MIDI enabled");
      return device;
    }

    free(device);
  } else {
    logMallocError();
  }

  logMessage(LOG_DEBUG, "MIDI not available");
  return NULL;
}

static void
midiDestruct (NoteDevice *device) {
  closeMidiDevice(device->midi);
  free(device);
  logMessage(LOG_DEBUG, "MIDI disabled");
}

static int
midiNote (NoteDevice *device, unsigned int duration, unsigned char note) {
  logMessage(LOG_DEBUG, "tone: MSecs:%u Note:%u", duration, note);
  beginMidiBlock(device->midi);

  if (note) {
    startMidiNote(device->midi, device->channelNumber, note, prefs.midiVolume);
    insertMidiWait(device->midi, duration);
    stopMidiNote(device->midi, device->channelNumber);
  } else {
    insertMidiWait(device->midi, duration);
  }

  endMidiBlock(device->midi);
  return 1;
}

static int
midiTone (NoteDevice *device, unsigned int duration, NoteFrequency frequency) {
  return midiNote(device, duration, getNearestNote(frequency));
}

static int
midiFlush (NoteDevice *device) {
  return flushMidiDevice(device->midi);
}

const NoteMethods midiNoteMethods = {
  .construct = midiConstruct,
  .destruct = midiDestruct,

  .tone = midiTone,
  .note = midiNote,
  .flush = midiFlush
};
