/*
 * 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 <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>

#include "log.h"
#include "midi.h"

struct MidiDeviceStruct {
  AUGraph graph;
  AudioUnit synth;
  /* Note that is currently playing. */
  int note;
};
  
MidiDevice *
openMidiDevice (int errorLevel, const char *device) {
  MidiDevice *midi;
  int result;
  AUNode synthNode, outNode;
  ComponentDescription cd;
  UInt32 propVal;

  if (!(midi = malloc(sizeof(*midi)))) {
    logMallocError();
    return NULL;
  }

  /* Create a graph with a software synth and a default output unit. */

  cd.componentManufacturer = kAudioUnitManufacturer_Apple;
  cd.componentFlags = 0;
  cd.componentFlagsMask = 0;

  if ((result = NewAUGraph(&midi->graph)) != noErr) {
    logMessage(errorLevel, "Can't create audio graph component: %d", result);
    goto err;
  }

  cd.componentType = kAudioUnitType_MusicDevice;
  cd.componentSubType = kAudioUnitSubType_DLSSynth;
  if ((result = AUGraphNewNode(midi->graph, &cd, 0, NULL, &synthNode))
      != noErr) {
    logMessage(errorLevel, "Can't create software synthersizer component: %d",
	       result);
    goto err;
  }

  cd.componentType = kAudioUnitType_Output;
  cd.componentSubType = kAudioUnitSubType_DefaultOutput;
  if ((result = AUGraphNewNode(midi->graph, &cd, 0, NULL, &outNode))
      != noErr) {
    logMessage(errorLevel, "Can't create default output audio component: %d",
	       result);
    goto err;
  }

  if ((result = AUGraphOpen(midi->graph)) != noErr) {
    logMessage(errorLevel, "Can't open audio graph component: %d", result);
    goto err;
  }

  if ((result = AUGraphConnectNodeInput(midi->graph, synthNode, 0, outNode, 0))
      != noErr) {
    logMessage(errorLevel, "Can't connect synth audio component to output: %d",
	       result);
    goto err;
  }

  if ((result = AUGraphGetNodeInfo(midi->graph, synthNode, 0, 0, 0,
				   &midi->synth)) != noErr) {
    logMessage(errorLevel, "Can't get audio component for software synth: %d",
	       result);
    goto err;
  }

  if ((result = AUGraphInitialize(midi->graph)) != noErr) {
    logMessage(errorLevel, "Can't initialize audio graph: %d", result);
    goto err;
  }

  /* Turn off the reverb.  The value range is -120 to 40 dB. */
  propVal = false;
  if ((result = AudioUnitSetProperty(midi->synth,
				     kMusicDeviceProperty_UsesInternalReverb,
				     kAudioUnitScope_Global, 0,
				     &propVal, sizeof(propVal)))
      != noErr) {
    /* So, having reverb isn't that critical, is it? */
    logMessage(LOG_DEBUG, "Can't turn of software synth reverb: %d",
	       result);
  }

  /* TODO: Maybe just start the graph when we are going to use it? */
  if ((result = AUGraphStart(midi->graph)) != noErr) {
    logMessage(errorLevel, "Can't start audio graph component: %d", result);
    goto err;
  }

  return midi;

 err:
  if (midi->graph)
    DisposeAUGraph(midi->graph);
  free(midi);
  return NULL;
}

void
closeMidiDevice (MidiDevice *midi) {
  int result;
  if (midi) {
    if ((result = DisposeAUGraph(midi->graph)) != noErr)
      logMessage(LOG_ERR, "Can't dispose audio graph component: %d", result);
    free(midi);
  }
}

int
flushMidiDevice (MidiDevice *midi) {
  return 1;
}

int
setMidiInstrument (MidiDevice *midi, unsigned char channel, unsigned char instrument) {
  int result;
  if ((result = MusicDeviceMIDIEvent(midi->synth, 0xC0 | channel, instrument,
				     0, 0)) != noErr)
    logMessage(LOG_ERR, "Can't set MIDI instrument: %d", result);

  return result == noErr;
}

int
beginMidiBlock (MidiDevice *midi) {
  return 1;
}

int
endMidiBlock (MidiDevice *midi) {
  return 1;
}

int
startMidiNote (MidiDevice *midi, unsigned char channel, unsigned char note, unsigned char volume) {
  int result;

  if ((result = MusicDeviceMIDIEvent(midi->synth, 0x90 | channel, note,
				     volume, 0)) != noErr) {
    logMessage(LOG_ERR, "Can't start MIDI note: %d", result);
    return 0;
  }
  midi->note = note;

  return 1;
}

int
stopMidiNote (MidiDevice *midi, unsigned char channel) {
  int result;

  if ((result = MusicDeviceMIDIEvent(midi->synth, 0x90 | channel, midi->note,
				     0, 0)) != noErr) {
    logMessage(LOG_ERR, "Can't stop MIDI note: %d", result);
    return 0;
  }
  midi->note = 0;

  return 1;
}

int
insertMidiWait (MidiDevice *midi, int duration) {
  usleep(duration * 1000);
  return 1;
}
