2017-06-19 06:46:08 +02:00
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "munt/c_interface/c_interface.h"
|
|
|
|
|
#include "../WIN/plat_thread.h"
|
2017-07-15 18:37:06 +02:00
|
|
|
#include "../WIN/plat_ticks.h"
|
2017-06-19 06:46:08 +02:00
|
|
|
#include "../ibm.h"
|
|
|
|
|
#include "../device.h"
|
|
|
|
|
#include "../mem.h"
|
|
|
|
|
#include "../rom.h"
|
|
|
|
|
#include "midi_mt32.h"
|
|
|
|
|
#include "midi.h"
|
|
|
|
|
#include "sound.h"
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
#define RENDER_RATE 30
|
|
|
|
|
#define MESSAGE_HIDE 10000
|
|
|
|
|
|
2017-06-19 06:46:08 +02:00
|
|
|
extern void givealbuffer_midi(void *buf, uint32_t size);
|
|
|
|
|
extern void pclog(const char *format, ...);
|
|
|
|
|
extern void al_set_midi(int freq, int buf_size);
|
2017-07-15 18:37:06 +02:00
|
|
|
extern int soundon;
|
|
|
|
|
|
|
|
|
|
typedef struct mt32_t
|
|
|
|
|
{
|
|
|
|
|
mt32emu_context context;
|
|
|
|
|
char message[MT32EMU_SYSEX_BUFFER_SIZE];
|
|
|
|
|
unsigned int message_shown;
|
|
|
|
|
thread_t* thread_h;
|
|
|
|
|
event_t* event;
|
|
|
|
|
|
|
|
|
|
uint32_t samplerate;
|
|
|
|
|
int buf_size;
|
|
|
|
|
float* buffer;
|
|
|
|
|
int16_t* buffer_int16;
|
|
|
|
|
int midi_pos;
|
|
|
|
|
|
|
|
|
|
int status_show_instruments;
|
|
|
|
|
|
|
|
|
|
char model_name[50];
|
|
|
|
|
} mt32_t;
|
|
|
|
|
|
|
|
|
|
void showLCDMessage(void *instance_data, const char *message)
|
|
|
|
|
{
|
|
|
|
|
mt32_t* data = (mt32_t*)instance_data;
|
|
|
|
|
strncpy(data->message, message, 999);
|
|
|
|
|
data->message[999] = 0;
|
|
|
|
|
data->message_shown = get_ticks();
|
|
|
|
|
}
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
static const mt32emu_report_handler_i_v0 handler_v0 = {
|
|
|
|
|
/** Returns the actual interface version ID */
|
|
|
|
|
NULL, //mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i);
|
|
|
|
|
|
|
|
|
|
/** Callback for debug messages, in vprintf() format */
|
|
|
|
|
NULL, //void (*printDebug)(void *instance_data, const char *fmt, va_list list);
|
|
|
|
|
/** Callbacks for reporting errors */
|
|
|
|
|
NULL, //void (*onErrorControlROM)(void *instance_data);
|
|
|
|
|
NULL, //void (*onErrorPCMROM)(void *instance_data);
|
|
|
|
|
/** Callback for reporting about displaying a new custom message on LCD */
|
2017-07-15 18:37:06 +02:00
|
|
|
showLCDMessage, //void (*showLCDMessage)(void *instance_data, const char *message);
|
2017-06-19 06:46:08 +02:00
|
|
|
/** Callback for reporting actual processing of a MIDI message */
|
|
|
|
|
NULL, //void (*onMIDIMessagePlayed)(void *instance_data);
|
|
|
|
|
/**
|
|
|
|
|
* Callback for reporting an overflow of the input MIDI queue.
|
|
|
|
|
* Returns MT32EMU_BOOL_TRUE if a recovery action was taken
|
|
|
|
|
* and yet another attempt to enqueue the MIDI event is desired.
|
|
|
|
|
*/
|
|
|
|
|
NULL, //mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data);
|
|
|
|
|
/**
|
|
|
|
|
* Callback invoked when a System Realtime MIDI message is detected in functions
|
|
|
|
|
* mt32emu_parse_stream and mt32emu_play_short_message and the likes.
|
|
|
|
|
*/
|
|
|
|
|
NULL, //void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime);
|
|
|
|
|
/** Callbacks for reporting system events */
|
|
|
|
|
NULL, //void (*onDeviceReset)(void *instance_data);
|
|
|
|
|
NULL, //void (*onDeviceReconfig)(void *instance_data);
|
|
|
|
|
/** Callbacks for reporting changes of reverb settings */
|
|
|
|
|
NULL, //void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode);
|
|
|
|
|
NULL, //void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time);
|
|
|
|
|
NULL, //void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level);
|
|
|
|
|
/** Callbacks for reporting various information */
|
|
|
|
|
NULL, //void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num);
|
|
|
|
|
NULL, //void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const mt32emu_report_handler_i handler = { &handler_v0 };
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
static int roms_present[] = { -1, -1 };
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
mt32emu_return_code mt32_check(const char* func, mt32emu_return_code ret, mt32emu_return_code expected)
|
|
|
|
|
{
|
|
|
|
|
if (ret != expected)
|
|
|
|
|
{
|
|
|
|
|
pclog("%s() failed, expected %d but returned %d\n", func, expected, ret);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int mt32_available()
|
|
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
if (roms_present[0] < 0)
|
|
|
|
|
roms_present[0] = (rom_present(L"roms/mt32/mt32_control.rom") && rom_present(L"roms/mt32/mt32_pcm.rom"));
|
|
|
|
|
return roms_present[0];
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
int cm32l_available()
|
|
|
|
|
{
|
|
|
|
|
if (roms_present[1] < 0)
|
|
|
|
|
roms_present[1] = (rom_present(L"roms/cm32l/cm32l_control.rom") && rom_present(L"roms/cm32l/cm32l_pcm.rom"));
|
|
|
|
|
return roms_present[1];
|
|
|
|
|
}
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_stream(mt32emu_context context, float* stream, int len)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
|
|
|
|
if (context) mt32emu_render_float(context, stream, len);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_stream_int16(mt32emu_context context, int16_t* stream, int len)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
|
|
|
|
if (context) mt32emu_render_bit16s(context, stream, len);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_poll(midi_device_t *device)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_t *data = (mt32_t *) device->data;
|
|
|
|
|
data->midi_pos++;
|
|
|
|
|
if (data->midi_pos == 48000/RENDER_RATE)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
data->midi_pos = 0;
|
|
|
|
|
thread_set_event(data->event);
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
2017-07-15 18:37:06 +02:00
|
|
|
if (get_ticks() > data->message_shown+MESSAGE_HIDE)
|
|
|
|
|
data->message[0] = 0;
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mt32_thread(void *param)
|
|
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_t *data = (mt32_t *) param;
|
2017-06-19 06:46:08 +02:00
|
|
|
while (1)
|
|
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
thread_wait_event(data->event, -1);
|
2017-06-19 06:46:08 +02:00
|
|
|
if (sound_is_float)
|
|
|
|
|
{
|
2017-07-15 18:56:25 +02:00
|
|
|
memset(data->buffer, 0, data->buf_size);
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_stream(data->context, data->buffer, data->buf_size / (sizeof(float) << 1));
|
2017-06-19 06:46:08 +02:00
|
|
|
if (soundon)
|
2017-07-15 18:37:06 +02:00
|
|
|
givealbuffer_midi(data->buffer, data->buf_size);
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-07-15 18:56:25 +02:00
|
|
|
memset(data->buffer_int16, 0, data->buf_size);
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_stream_int16(data->context, data->buffer_int16, data->buf_size / (sizeof(int16_t) << 1));
|
2017-06-19 06:46:08 +02:00
|
|
|
if (soundon)
|
2017-07-15 18:37:06 +02:00
|
|
|
givealbuffer_midi(data->buffer_int16, data->buf_size);
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_msg(midi_device_t *device, uint8_t* val)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32emu_context context = ((mt32_t *)device->data)->context;
|
2017-06-19 06:46:08 +02:00
|
|
|
if (context) mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t*)val), MT32EMU_RC_OK);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_sysex(midi_device_t *device, uint8_t* data, unsigned int len)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32emu_context context = ((mt32_t *)device->data)->context;
|
2017-06-19 06:46:08 +02:00
|
|
|
if (context) mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
static mt32emu_return_code mt32emu_add_rom_file_ex(mt32emu_context context, wchar_t *s)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
char fn[512];
|
2017-06-19 06:46:08 +02:00
|
|
|
wcstombs(fn, s, (wcslen(s) << 1) + 2);
|
2017-07-15 18:37:06 +02:00
|
|
|
return mt32emu_add_rom_file(context, fn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void* mt32emu_init(wchar_t* control_rom, wchar_t* pcm_rom)
|
|
|
|
|
{
|
|
|
|
|
wchar_t s[512];
|
|
|
|
|
|
|
|
|
|
mt32_t* data = malloc(sizeof(mt32_t));
|
|
|
|
|
memset(data, 0, sizeof(mt32_t));
|
|
|
|
|
mt32emu_context context = mt32emu_create_context(handler, data);
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
if (
|
|
|
|
|
!rom_getfile(control_rom, s, 512) ||
|
|
|
|
|
!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file_ex(context, s), MT32EMU_RC_ADDED_CONTROL_ROM) ||
|
|
|
|
|
!rom_getfile(pcm_rom, s, 512) ||
|
|
|
|
|
!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file_ex(context, s), MT32EMU_RC_ADDED_PCM_ROM) ||
|
|
|
|
|
!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK))
|
|
|
|
|
{
|
|
|
|
|
free(data);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
data->samplerate = mt32emu_get_actual_stereo_output_samplerate(context);
|
2017-06-19 06:46:08 +02:00
|
|
|
if (sound_is_float)
|
|
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
data->buf_size = data->samplerate/RENDER_RATE*(sizeof(float) << 1);
|
|
|
|
|
data->buffer = malloc(data->buf_size);
|
|
|
|
|
data->buffer_int16 = NULL;
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
data->buf_size = data->samplerate/RENDER_RATE*(sizeof(int16_t) << 1);
|
|
|
|
|
data->buffer = NULL;
|
|
|
|
|
data->buffer_int16 = malloc(data->buf_size);
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
2017-07-15 18:37:06 +02:00
|
|
|
data->event = thread_create_event();
|
2017-07-15 18:56:25 +02:00
|
|
|
data->thread_h = thread_create(mt32_thread, data);
|
2017-07-15 18:37:06 +02:00
|
|
|
data->status_show_instruments = device_get_config_int("status_show_instruments");
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f);
|
|
|
|
|
mt32emu_set_reverb_enabled(context, device_get_config_int("reverb"));
|
|
|
|
|
mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain")/100.0f);
|
|
|
|
|
mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo"));
|
|
|
|
|
|
|
|
|
|
pclog("mt32 output gain: %f\n", mt32emu_get_output_gain(context));
|
|
|
|
|
pclog("mt32 reverb output gain: %f\n", mt32emu_get_reverb_output_gain(context));
|
|
|
|
|
pclog("mt32 reverb: %d\n", mt32emu_is_reverb_enabled(context));
|
|
|
|
|
pclog("mt32 reversed stereo: %d\n", mt32emu_is_reversed_stereo_enabled(context));
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
al_set_midi(data->samplerate, data->buf_size);
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
pclog("mt32 (Munt %s) initialized, samplerate %d, buf_size %d\n", mt32emu_get_library_version_string(), data->samplerate, data->buf_size);
|
|
|
|
|
|
|
|
|
|
data->context = context;
|
|
|
|
|
data->message[0] = 0;
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
midi_device_t* dev = malloc(sizeof(midi_device_t));
|
|
|
|
|
memset(dev, 0, sizeof(midi_device_t));
|
|
|
|
|
|
|
|
|
|
dev->play_msg = mt32_msg;
|
|
|
|
|
dev->play_sysex = mt32_sysex;
|
|
|
|
|
dev->poll = mt32_poll;
|
2017-07-15 18:37:06 +02:00
|
|
|
dev->data = data;
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
midi_init(dev);
|
|
|
|
|
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void* mt32_init()
|
|
|
|
|
{
|
|
|
|
|
midi_device_t* dev = mt32emu_init(L"roms/mt32/mt32_control.rom", L"roms/mt32/mt32_pcm.rom");
|
|
|
|
|
if (dev)
|
|
|
|
|
strcpy(((mt32_t*)dev->data)->model_name, "MT-32");
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* cm32l_init()
|
|
|
|
|
{
|
|
|
|
|
midi_device_t* dev = mt32emu_init(L"roms/cm32l/cm32l_control.rom", L"roms/cm32l/cm32l_pcm.rom");
|
|
|
|
|
if (dev)
|
|
|
|
|
strcpy(((mt32_t*)dev->data)->model_name, "CM-32L");
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-19 06:46:08 +02:00
|
|
|
void mt32_close(void* p)
|
|
|
|
|
{
|
|
|
|
|
if (!p) return;
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
midi_device_t* device = (midi_device_t*)p;
|
|
|
|
|
|
|
|
|
|
mt32_t* data = (mt32_t*)device->data;
|
|
|
|
|
|
|
|
|
|
if (data->thread_h)
|
|
|
|
|
thread_kill(data->thread_h);
|
|
|
|
|
if (data->event)
|
|
|
|
|
thread_destroy_event(data->event);
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
if (data->context)
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32emu_close_synth(data->context);
|
|
|
|
|
mt32emu_free_context(data->context);
|
2017-06-19 06:46:08 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
if (data->buffer)
|
|
|
|
|
free(data->buffer);
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
if (data->buffer_int16)
|
|
|
|
|
free(data->buffer_int16);
|
2017-06-19 06:46:08 +02:00
|
|
|
|
|
|
|
|
midi_close();
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
free(data);
|
2017-06-19 06:46:08 +02:00
|
|
|
free((midi_device_t*)p);
|
|
|
|
|
|
|
|
|
|
pclog("mt32 closed\n");
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-15 18:37:06 +02:00
|
|
|
void mt32_add_status_info(char *s, int max_len, void *p)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
char temps[MT32EMU_SYSEX_BUFFER_SIZE];
|
|
|
|
|
midi_device_t* dev = (midi_device_t*)p;
|
|
|
|
|
mt32_t* data = (mt32_t*)dev->data;
|
|
|
|
|
mt32emu_context context = data->context;
|
|
|
|
|
if (strlen(data->message))
|
|
|
|
|
{
|
|
|
|
|
sprintf(temps, "%s message: %s\n", data->model_name, data->message);
|
|
|
|
|
strncat(s, temps, max_len);
|
|
|
|
|
}
|
|
|
|
|
if (mt32emu_is_active(context))
|
|
|
|
|
{
|
|
|
|
|
sprintf(temps, "%s playback frequency: %iHz\n", data->model_name, data->samplerate);
|
|
|
|
|
strncat(s, temps, max_len);
|
|
|
|
|
if (data->status_show_instruments)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < 8; ++i)
|
|
|
|
|
{
|
|
|
|
|
const char* patch_name = mt32emu_get_patch_name(context, i);
|
|
|
|
|
sprintf(temps, "%s inst. %d: %s\n", data->model_name, i+1, patch_name);
|
|
|
|
|
strncat(s, temps, max_len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
strncat(s, "\n", max_len);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strncat(s, data->model_name, max_len);
|
|
|
|
|
strncat(s, " playback stopped\n\n", max_len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-19 06:46:08 +02:00
|
|
|
static device_config_t mt32_config[] =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
.name = "output_gain",
|
|
|
|
|
.description = "Output Gain",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
.description = "100%",
|
|
|
|
|
.value = 100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "75%",
|
|
|
|
|
.value = 75
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "50%",
|
|
|
|
|
.value = 50
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "25%",
|
|
|
|
|
.value = 25
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "0%",
|
|
|
|
|
.value = 0
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
.default_int = 100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "reverb",
|
|
|
|
|
.description = "Reverb",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "reverb_output_gain",
|
|
|
|
|
.description = "Reverb Output Gain",
|
|
|
|
|
.type = CONFIG_SELECTION,
|
|
|
|
|
.selection =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
.description = "100%",
|
|
|
|
|
.value = 100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "75%",
|
|
|
|
|
.value = 75
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "50%",
|
|
|
|
|
.value = 50
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "25%",
|
|
|
|
|
.value = 25
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = "0%",
|
|
|
|
|
.value = 0
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.description = ""
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
.default_int = 100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.name = "reversed_stereo",
|
|
|
|
|
.description = "Reversed stereo",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 0
|
|
|
|
|
},
|
2017-07-15 18:37:06 +02:00
|
|
|
{
|
|
|
|
|
.name = "status_show_instruments",
|
|
|
|
|
.description = "(Status) Show instruments",
|
|
|
|
|
.type = CONFIG_BINARY,
|
|
|
|
|
.default_int = 0
|
|
|
|
|
},
|
2017-06-19 06:46:08 +02:00
|
|
|
{
|
|
|
|
|
.type = -1
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
device_t mt32_device =
|
|
|
|
|
{
|
|
|
|
|
"Roland MT-32 Emulation",
|
|
|
|
|
0,
|
|
|
|
|
mt32_init,
|
|
|
|
|
mt32_close,
|
|
|
|
|
mt32_available,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_add_status_info,
|
|
|
|
|
mt32_config
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
device_t cm32l_device =
|
|
|
|
|
{
|
|
|
|
|
"Roland CM-32L Emulation",
|
|
|
|
|
0,
|
|
|
|
|
cm32l_init,
|
|
|
|
|
mt32_close,
|
|
|
|
|
cm32l_available,
|
|
|
|
|
NULL,
|
2017-06-19 06:46:08 +02:00
|
|
|
NULL,
|
2017-07-15 18:37:06 +02:00
|
|
|
mt32_add_status_info,
|
2017-06-19 06:46:08 +02:00
|
|
|
mt32_config
|
|
|
|
|
};
|