Further improved mt32emu_alsadrv:

- analog emulation mode made configurable
- ROM search dir can be specified in command line
- ROM search algo is now controlled by a single option,
  previous behaviour is also retained by default
- in the Makefile, added compiler options to suppress various annoying warnings
- when installing, roms directory is no longer required (and copied)
This commit is contained in:
sergm
2017-03-24 21:27:23 +02:00
parent 9287fe4acf
commit c0d3dcc3c2
5 changed files with 122 additions and 96 deletions

View File

@@ -1,4 +1,4 @@
CXXFLAGS=-O2 -DANALOG_MODE=2
CXXFLAGS=-O2 -Wno-write-strings -Wno-unused-result -Wno-deprecated-declarations
LIBS=-lmt32emu -lm -lasound -lpthread
XLIBS=-L/usr/X11R6/lib -lX11 -lXt -lXpm
@@ -20,9 +20,6 @@ xmt32: $(OBJS) $(XOBJ) src/xmt32.cpp
install:
install mt32d /usr/local/bin
install xmt32 /usr/local/bin
install -d roms /usr/share/mt32-rom-data
cd roms; install * /usr/share/mt32-rom-data
cd /usr/share/mt32-rom-data; chmod 644 *
clean:
rm -f *.o *~

View File

@@ -44,7 +44,7 @@ char *recwav_filename = NULL;
FILE *recwav_file = NULL;
#define PERC_CHANNEL 9
char rom_path[] = "/usr/share/mt32-rom-data/";
const char default_rom_dir[] = "/usr/share/mt32-rom-data/";
#include <mt32emu/mt32emu.h>
@@ -97,20 +97,11 @@ snd_seq_t *seq_handle = NULL;
#define FRAGMENT_SIZE 256 // 2 milliseconds
#define PERIOD_SIZE 128 // 1 millisecond
#if ANALOG_MODE == 3
static const MT32Emu::AnalogOutputMode ANALOG_OUTPUT_MODE = MT32Emu::AnalogOutputMode_OVERSAMPLED;
const int SAMPLE_RATE = 96000;
#elif ANALOG_MODE == 2
static const MT32Emu::AnalogOutputMode ANALOG_OUTPUT_MODE = MT32Emu::AnalogOutputMode_ACCURATE;
const int SAMPLE_RATE = 48000;
#else
#if ANALOG_MODE == 1
static const MT32Emu::AnalogOutputMode ANALOG_OUTPUT_MODE = MT32Emu::AnalogOutputMode_COARSE;
#else
static const MT32Emu::AnalogOutputMode ANALOG_OUTPUT_MODE = MT32Emu::AnalogOutputMode_DIGITAL_ONLY;
#endif
const int SAMPLE_RATE = 32000;
#endif
MT32Emu::AnalogOutputMode analog_output_mode = MT32Emu::AnalogOutputMode_ACCURATE;
unsigned int sample_rate = 48000;
char *rom_dir = NULL;
enum rom_search_type_t rom_search_type;
int buffermsec = 100;
int minimum_msec = 40;
@@ -124,7 +115,7 @@ int events_qd = 0;
int tempo = -1, ppq = -1;
double timepertick = -1;
double bytespermsec = (double)(SAMPLE_RATE * 2 * 2) / 1000000.0;
double bytespermsec = (double)(sample_rate * 2 * 2) / 1000000.0;
int channelmap[16];
int channeluse[16];
@@ -178,7 +169,7 @@ int alsa_set_buffer_time(int msec)
unsigned int v, rate, periods;
double sec, tpp;
rate = SAMPLE_RATE;
rate = sample_rate;
channels = 2;
sec = (double)msec / 1000.0;
@@ -911,7 +902,7 @@ int init_alsadrv()
exit(1);
/* create pcm thread if needed */
alsa_init_pcm(SAMPLE_RATE, 2);
alsa_init_pcm(sample_rate, 2);
/* create communication pipe from alsa reader to processor */
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, eventpipe))
@@ -949,7 +940,44 @@ int init_alsadrv()
return 0;
}
void reload_mt32_core(int rv, int mode)
static bool tryROMFile(const char romDir[], const char filename[], MT32Emu::FileStream &romFile) {
static const int MAX_PATH_LENGTH = 4096;
if ((strlen(romDir) + strlen(filename) + 1) > MAX_PATH_LENGTH) {
return false;
}
char romPathName[MAX_PATH_LENGTH];
strcpy(romPathName, romDir);
strcat(romPathName, filename);
return romFile.open(romPathName);
}
static void openROMFile(const char romDir[], const char romFile1[], const char romFile2[], MT32Emu::FileStream &romFile, const char romType[]) {
switch (rom_search_type) {
case ROM_SEARCH_TYPE_CM32L_ONLY:
if (!tryROMFile(romDir, romFile1, romFile)) {
report(DRV_MT32ROMFAIL, romType);
exit(1);
}
break;
case ROM_SEARCH_TYPE_MT32_ONLY:
if (!tryROMFile(romDir, romFile2, romFile)) {
report(DRV_MT32ROMFAIL, romType);
exit(1);
}
break;
default:
if (!tryROMFile(romDir, romFile1, romFile)) {
if (!tryROMFile(romDir, romFile2, romFile)) {
report(DRV_MT32ROMFAIL, romType);
exit(1);
}
}
break;
}
}
void reload_mt32_core(int rv)
{
/* delete core if there is already an instance of it */
if (mt32 != NULL)
@@ -965,51 +993,23 @@ void reload_mt32_core(int rv, int mode)
MT32Emu::FileStream controlROMFile;
MT32Emu::FileStream pcmROMFile;
char controlROMFileName[256];
if (mode==1) {
strcpy(controlROMFileName, rom_path);
strcat(controlROMFileName, "CM32L_CONTROL.ROM");
}
else if (mode==2) {
strcpy(controlROMFileName, rom_path);
strcat(controlROMFileName, "MT32_CONTROL.ROM");
}
else {
report(DRV_MT32ROMFAIL, "Control");
exit(1);
char romDir[4096];
if (rom_dir != NULL) {
strcpy(romDir, rom_dir);
strcat(romDir, "/");
} else {
strcpy(romDir, default_rom_dir);
}
if (!controlROMFile.open(controlROMFileName)) {
report(DRV_MT32ROMFAIL, "Control");
exit(1);
}
char pcmROMFileName[256];
if (mode==1) {
strcpy(pcmROMFileName, rom_path);
strcat(pcmROMFileName, "CM32L_PCM.ROM");
}
else if (mode==2) {
strcpy(pcmROMFileName, rom_path);
strcat(pcmROMFileName, "MT32_PCM.ROM");
}
else {
report(DRV_MT32ROMFAIL, "PCM");
exit(1);
}
if (!pcmROMFile.open(pcmROMFileName)) {
report(DRV_MT32ROMFAIL, "PCM");
exit(1);
}
openROMFile(romDir, "CM32L_CONTROL.ROM", "MT32_CONTROL.ROM", controlROMFile, "Control");
openROMFile(romDir, "CM32L_PCM.ROM", "MT32_PCM.ROM", pcmROMFile, "PCM");
const MT32Emu::ROMImage *controlROMImage = MT32Emu::ROMImage::makeROMImage(&controlROMFile);
const MT32Emu::ROMImage *pcmROMImage = MT32Emu::ROMImage::makeROMImage(&pcmROMFile);
/* create MT32Synth object */
mt32 = new MT32Emu::Synth(mt32ReportHandler);
if (mt32->open(*controlROMImage, *pcmROMImage, ANALOG_OUTPUT_MODE) == false) {
if (mt32->open(*controlROMImage, *pcmROMImage, analog_output_mode) == false) {
report(DRV_MT32FAIL);
exit(1);
}
@@ -1027,7 +1027,7 @@ void reload_mt32_core(int rv, int mode)
mt32->setReverbOutputGain(gain_multiplier);
}
int process_loop(int rv, int mode)
int process_loop(int rv)
{
unsigned char processbuffer[FRAGMENT_SIZE];
unsigned int msg;
@@ -1047,7 +1047,7 @@ int process_loop(int rv, int mode)
rv_level = 3;
consumer_types = 0;
reload_mt32_core(rv, mode);
reload_mt32_core(rv);
/* setup poll info */
event_poll.fd = eventpipe[0];
@@ -1201,8 +1201,8 @@ int process_loop(int rv, int mode)
break;
case EVENT_RESET:
reload_mt32_core(rv, mode);
break;
reload_mt32_core(rv);
break;
case EVENT_WAVREC_ON:
start_recordwav();

View File

@@ -80,19 +80,25 @@ void send_rvtime_sysex(int newtime);
void send_rvlevel_sysex(int newlevel);
extern int alsa_buffer_size;
extern char rom_path[];
extern int eventpipe[];
extern char *pcm_name;
extern double gain_multiplier;
extern MT32Emu::AnalogOutputMode analog_output_mode;
extern unsigned int sample_rate;
extern char *rom_dir;
extern enum rom_search_type_t {
ROM_SEARCH_TYPE_DEFAULT,
ROM_SEARCH_TYPE_CM32L_ONLY,
ROM_SEARCH_TYPE_MT32_ONLY
} rom_search_type;
int init_alsadrv();
int process_loop(int rv, int mode);
int process_loop(int rv);
extern MT32Emu::Synth *mt32;
#endif

View File

@@ -134,10 +134,15 @@ void usage(char *argv[])
printf("\n");
printf("-g factor : Gain multiplier (default: 1.0) \n");
printf("-l mode : Analog emulation mode (0 - Digital, 1 - Coarse,"
" 2 - Accurate, 3 - Oversampled 2x, default: 2)\n");
printf("\n");
printf("-o : Load MT32 Firmware \n");
printf("-c : Load CM32L Firmware (Default) \n");
printf("-f romdir : Directory with ROM files to load"
" (default: '/usr/share/mt32-rom-data/')\n");
printf("-o romsearch : Search algorithm to use when loading ROM files:"
" (0 - try both but CM32-L first, 1 - CM32-L only,"
" 2 - MT-32 only, default: 0)\n");
printf("\n");
@@ -149,8 +154,7 @@ int main(int argc, char **argv)
{
int reverb_switch = 1;
int i;
int mode=2;
/* parse the options */
for (i = 1; i < argc; i++)
{
@@ -159,12 +163,6 @@ int main(int argc, char **argv)
switch(argv[i][1])
{
case 'o':
mode=2;
break;
case 'c':
mode=1;
break;
case 'w':
i++;
if (i == argc)
@@ -216,6 +214,22 @@ int main(int argc, char **argv)
case 'g': i++; if (i == argc) usage(argv);
gain_multiplier = atof(argv[i]);
break;
case 'l': i++; if (i == argc) usage(argv);
analog_output_mode = MT32Emu::AnalogOutputMode(atoi(argv[i]));
if (analog_output_mode < MT32Emu::AnalogOutputMode_DIGITAL_ONLY
|| MT32Emu::AnalogOutputMode_OVERSAMPLED < analog_output_mode) usage(argv);
sample_rate = MT32Emu::Synth::getStereoOutputSampleRate(analog_output_mode);
break;
case 'f': i++; if (i == argc) usage(argv);
rom_dir = new char[strlen(argv[i]) + 1];
strcpy(rom_dir, argv[i]);
break;
case 'o': i++; if (i == argc) usage(argv);
rom_search_type = rom_search_type_t(atoi(argv[i]));
if (rom_search_type < ROM_SEARCH_TYPE_DEFAULT
|| ROM_SEARCH_TYPE_MT32_ONLY < rom_search_type) usage(argv);
break;
default:
usage(argv);
@@ -228,7 +242,7 @@ int main(int argc, char **argv)
exit(1);
}
process_loop(reverb_switch, mode);
process_loop(reverb_switch);
return 0;
}

View File

@@ -480,14 +480,19 @@ void usage(char *argv[])
printf("-i msec : Minimum (initial) buffer size in milliseconds\n");
printf("\n");
printf("-d name : ALSA PCM device name (default: \"default\") \n");
printf("-d name : ALSA PCM device name (default: \"default\")\n");
printf("\n");
printf("-g factor : Gain multiplier (default: 1.0) \n");
printf("-l mode : Analog emulation mode (0 - Digital, 1 - Coarse,"
" 2 - Accurate, 3 - Oversampled 2x, default: 2)\n");
printf("\n");
printf("-o : Load MT32 Firmware \n");
printf("-c : Load CM32L Firmware (Default) \n");
printf("-f romdir : Directory with ROM files to load"
" (default: '/usr/share/mt32-rom-data/')\n");
printf("-o romsearch : Search algorithm to use when loading ROM files:"
" (0 - try both but CM32-L first, 1 - CM32-L only,"
" 2 - MT-32 only, default: 0)\n");
printf("\n");
exit(1);
@@ -498,8 +503,7 @@ int main(int argc, char *argv[])
{
pthread_t visthread;
int i;
int mode=2;
/* parse the options */
for (i = 1; i < argc; i++)
{
@@ -508,12 +512,6 @@ int main(int argc, char *argv[])
switch(argv[i][1])
{
case 'o':
mode=2;
break;
case 'c':
mode=1;
break;
case 'w':
i++; if (i == argc) usage(argv);
recwav_filename = (char *)malloc(strlen(argv[i]) + 1);
@@ -557,6 +555,22 @@ int main(int argc, char *argv[])
case 'g': i++; if (i == argc) usage(argv);
gain_multiplier = atof(argv[i]);
break;
case 'l': i++; if (i == argc) usage(argv);
analog_output_mode = MT32Emu::AnalogOutputMode(atoi(argv[i]));
if (analog_output_mode < MT32Emu::AnalogOutputMode_DIGITAL_ONLY
|| MT32Emu::AnalogOutputMode_OVERSAMPLED < analog_output_mode) usage(argv);
sample_rate = MT32Emu::Synth::getStereoOutputSampleRate(analog_output_mode);
break;
case 'f': i++; if (i == argc) usage(argv);
rom_dir = new char[strlen(argv[i]) + 1];
strcpy(rom_dir, argv[i]);
break;
case 'o': i++; if (i == argc) usage(argv);
rom_search_type = rom_search_type_t(atoi(argv[i]));
if (rom_search_type < ROM_SEARCH_TYPE_DEFAULT
|| ROM_SEARCH_TYPE_MT32_ONLY < rom_search_type) usage(argv);
break;
default:
usage(argv);
@@ -581,12 +595,7 @@ int main(int argc, char *argv[])
usleep(10000);
}
process_loop(xreverb_switch, mode);
process_loop(xreverb_switch);
return 0;
}