Different approach to CM-32L emulation, fixes it and MT-32.

This commit is contained in:
OBattler
2017-07-15 20:07:38 +02:00
parent 7c54006355
commit cc63eafce0
9 changed files with 145 additions and 248 deletions

View File

@@ -3,7 +3,6 @@
#include <string.h>
#include "munt/c_interface/c_interface.h"
#include "../WIN/plat_thread.h"
#include "../WIN/plat_ticks.h"
#include "../ibm.h"
#include "../device.h"
#include "../mem.h"
@@ -12,40 +11,9 @@
#include "midi.h"
#include "sound.h"
#define RENDER_RATE 30
#define MESSAGE_HIDE 10000
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);
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();
}
static const mt32emu_report_handler_i_v0 handler_v0 = {
/** Returns the actual interface version ID */
@@ -57,7 +25,7 @@ static const mt32emu_report_handler_i_v0 handler_v0 = {
NULL, //void (*onErrorControlROM)(void *instance_data);
NULL, //void (*onErrorPCMROM)(void *instance_data);
/** Callback for reporting about displaying a new custom message on LCD */
showLCDMessage, //void (*showLCDMessage)(void *instance_data, const char *message);
NULL, //void (*showLCDMessage)(void *instance_data, const char *message);
/** Callback for reporting actual processing of a MIDI message */
NULL, //void (*onMIDIMessagePlayed)(void *instance_data);
/**
@@ -85,7 +53,8 @@ static const mt32emu_report_handler_i_v0 handler_v0 = {
static const mt32emu_report_handler_i handler = { &handler_v0 };
static int roms_present[] = { -1, -1 };
static mt32emu_context context = NULL;
static int roms_present[2] = {-1, -1};
mt32emu_return_code mt32_check(const char* func, mt32emu_return_code ret, mt32emu_return_code expected)
{
@@ -111,106 +80,99 @@ int cm32l_available()
return roms_present[1];
}
void mt32_stream(mt32emu_context context, float* stream, int len)
static thread_t *thread_h = NULL;
static event_t *event = NULL;
#define RENDER_RATE 30
static uint32_t samplerate = 44100;
static int buf_size = 0;
static float* buffer = NULL;
static int16_t* buffer_int16 = NULL;
static int midi_pos = 0;
void mt32_stream(float* stream, int len)
{
if (context) mt32emu_render_float(context, stream, len);
}
void mt32_stream_int16(mt32emu_context context, int16_t* stream, int len)
void mt32_stream_int16(int16_t* stream, int len)
{
if (context) mt32emu_render_bit16s(context, stream, len);
}
void mt32_poll(midi_device_t *device)
void mt32_poll()
{
mt32_t *data = (mt32_t *) device->data;
data->midi_pos++;
if (data->midi_pos == 48000/RENDER_RATE)
midi_pos++;
if (midi_pos == 48000/RENDER_RATE)
{
data->midi_pos = 0;
thread_set_event(data->event);
midi_pos = 0;
thread_set_event(event);
}
if (get_ticks() > data->message_shown+MESSAGE_HIDE)
data->message[0] = 0;
}
extern int soundon;
static void mt32_thread(void *param)
{
mt32_t *data = (mt32_t *) param;
while (1)
{
thread_wait_event(data->event, -1);
thread_wait_event(event, -1);
if (sound_is_float)
{
memset(data->buffer, 0, data->buf_size);
mt32_stream(data->context, data->buffer, data->buf_size / (sizeof(float) << 1));
memset(buffer, 0, buf_size * sizeof(float));
mt32_stream(buffer, (samplerate/RENDER_RATE));
if (soundon)
givealbuffer_midi(data->buffer, data->buf_size);
givealbuffer_midi(buffer, buf_size);
}
else
{
memset(data->buffer_int16, 0, data->buf_size);
mt32_stream_int16(data->context, data->buffer_int16, data->buf_size / (sizeof(int16_t) << 1));
memset(buffer_int16, 0, buf_size * sizeof(int16_t));
mt32_stream_int16(buffer_int16, (samplerate/RENDER_RATE));
if (soundon)
givealbuffer_midi(data->buffer_int16, data->buf_size);
givealbuffer_midi(buffer_int16, buf_size);
}
}
}
void mt32_msg(midi_device_t *device, uint8_t* val)
void mt32_msg(uint8_t* val)
{
mt32emu_context context = ((mt32_t *)device->data)->context;
if (context) mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t*)val), MT32EMU_RC_OK);
}
void mt32_sysex(midi_device_t *device, uint8_t* data, unsigned int len)
void mt32_sysex(uint8_t* data, unsigned int len)
{
mt32emu_context context = ((mt32_t *)device->data)->context;
if (context) mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK);
}
static mt32emu_return_code mt32emu_add_rom_file_ex(mt32emu_context context, wchar_t *s)
{
char fn[512];
wcstombs(fn, s, (wcslen(s) << 1) + 2);
return mt32emu_add_rom_file(context, fn);
}
static void* mt32emu_init(wchar_t* control_rom, wchar_t* pcm_rom)
void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
{
wchar_t s[512];
char fn[512];
context = mt32emu_create_context(handler, NULL);
if (!rom_getfile(control_rom, s, 512)) return 0;
wcstombs(fn, s, (wcslen(s) << 1) + 2);
if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) return 0;
if (!rom_getfile(pcm_rom, s, 512)) return 0;
wcstombs(fn, s, (wcslen(s) << 1) + 2);
if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_PCM_ROM)) return 0;
mt32_t* data = malloc(sizeof(mt32_t));
memset(data, 0, sizeof(mt32_t));
mt32emu_context context = mt32emu_create_context(handler, data);
if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) return 0;
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;
}
data->samplerate = mt32emu_get_actual_stereo_output_samplerate(context);
event = thread_create_event();
thread_h = thread_create(mt32_thread, 0);
samplerate = mt32emu_get_actual_stereo_output_samplerate(context);
buf_size = samplerate/RENDER_RATE*2;
if (sound_is_float)
{
data->buf_size = data->samplerate/RENDER_RATE*(sizeof(float) << 1);
data->buffer = malloc(data->buf_size);
data->buffer_int16 = NULL;
buffer = malloc(buf_size * sizeof(float));
buffer_int16 = NULL;
}
else
{
data->buf_size = data->samplerate/RENDER_RATE*(sizeof(int16_t) << 1);
data->buffer = NULL;
data->buffer_int16 = malloc(data->buf_size);
buffer = NULL;
buffer_int16 = malloc(buf_size * sizeof(int16_t));
}
data->event = thread_create_event();
data->thread_h = thread_create(mt32_thread, data);
data->status_show_instruments = device_get_config_int("status_show_instruments");
mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f);
mt32emu_set_reverb_enabled(context, device_get_config_int("reverb"));
@@ -222,12 +184,9 @@ static void* mt32emu_init(wchar_t* control_rom, wchar_t* pcm_rom)
pclog("mt32 reverb: %d\n", mt32emu_is_reverb_enabled(context));
pclog("mt32 reversed stereo: %d\n", mt32emu_is_reversed_stereo_enabled(context));
al_set_midi(data->samplerate, data->buf_size);
al_set_midi(samplerate, buf_size);
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;
pclog("mt32 (Munt %s) initialized, samplerate %d, buf_size %d\n", mt32emu_get_library_version_string(), samplerate, buf_size);
midi_device_t* dev = malloc(sizeof(midi_device_t));
memset(dev, 0, sizeof(midi_device_t));
@@ -235,96 +194,55 @@ static void* mt32emu_init(wchar_t* control_rom, wchar_t* pcm_rom)
dev->play_msg = mt32_msg;
dev->play_sysex = mt32_sysex;
dev->poll = mt32_poll;
dev->data = data;
midi_init(dev);
return dev;
}
void* mt32_init()
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;
return mt32emu_init(L"roms/mt32/mt32_control.rom", L"roms/mt32/mt32_pcm.rom");
}
void* cm32l_init()
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;
return mt32emu_init(L"roms/cm32l/cm32l_control.rom", L"roms/cm32l/cm32l_pcm.rom");
}
void mt32_close(void* p)
{
if (!p) return;
midi_device_t* device = (midi_device_t*)p;
if (thread_h)
thread_kill(thread_h);
if (event)
thread_destroy_event(event);
event = NULL;
thread_h = NULL;
mt32_t* data = (mt32_t*)device->data;
if (data->thread_h)
thread_kill(data->thread_h);
if (data->event)
thread_destroy_event(data->event);
if (data->context)
if (context)
{
mt32emu_close_synth(data->context);
mt32emu_free_context(data->context);
mt32emu_close_synth(context);
mt32emu_free_context(context);
}
context = NULL;
if (data->buffer)
free(data->buffer);
if (buffer)
free(buffer);
buffer = NULL;
if (data->buffer_int16)
free(data->buffer_int16);
if (buffer_int16)
free(buffer_int16);
buffer_int16 = NULL;
midi_close();
free(data);
free((midi_device_t*)p);
pclog("mt32 closed\n");
}
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);
}
}
static device_config_t mt32_config[] =
{
{
@@ -403,12 +321,6 @@ static device_config_t mt32_config[] =
.type = CONFIG_BINARY,
.default_int = 0
},
{
.name = "status_show_instruments",
.description = "(Status) Show instruments",
.type = CONFIG_BINARY,
.default_int = 0
},
{
.type = -1
}
@@ -423,7 +335,7 @@ device_t mt32_device =
mt32_available,
NULL,
NULL,
mt32_add_status_info,
NULL,
mt32_config
};
@@ -436,6 +348,6 @@ device_t cm32l_device =
cm32l_available,
NULL,
NULL,
mt32_add_status_info,
NULL,
mt32_config
};