oplplayer/banktest.c
2025-03-20 11:02:57 +01:00

166 lines
4.5 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <errno.h>
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
void mid_log(char *format, ...) {
va_list ap;
va_start(ap, format);
char msg[1024];
msg[0] = 0;
vsprintf(msg, format, ap);
fprintf(stderr, "%s\n", msg);
va_end(ap);
}
#include "strings.h"
#include "opl3.h"
#include "dmx.h"
#include "bank.h"
#include "audio.h"
#define ARGPARSE_DE
#include "../argparse.h"
bool tst_note(aud_handle *dev, bank_instr *instr, opl3_chip *chip, bank_handle *bank, uint32_t samplerate, uint8_t prog, uint8_t note, uint32_t len, uint32_t pause) {
if(instr[prog].op == b_op0) {
return false;
}
uint8_t drum = prog >= 128;
if(drum) {
note = prog - 128;
}
int16_t buf[2];
if(drum) {
mid_log(STR_TST_DRUM, note, instr[128+note].name);
bank_noteon(bank, chip, 9, note, 127);
}
else {
mid_log(STR_TST_INSTR, note, prog, instr[prog].name);
bank_progchange(bank, chip, 0, prog);
bank_noteon(bank, chip, 0, note, 127);
}
for(int i = 0; i < ((samplerate*len)/1000); i++) {
OPL3_GenerateResampled(chip, buf);
aud_push(dev, buf);
}
bank_noteoff(bank, chip, drum ? 9 : 0, note, 0);
for(int i = 0; i < ((samplerate*pause)/1000); i++) {
OPL3_GenerateResampled(chip, buf);
aud_push(dev, buf);
}
return true;
}
bool tst_play(uint32_t samplerate, const char *dmxname, const char *drumname, uint8_t usedrum, const char *device, uint32_t fsize, uint32_t bufsize, uint8_t widefmt, uint8_t prog, uint8_t note, uint16_t offset, uint32_t len, uint32_t pause) {
bank_instr *instr = bnk_read_banks(dmxname, drumname, usedrum);
if(instr == NULL) {
return false;
}
if((offset == 256) && (instr[prog].op == b_op0)) {
fprintf(stderr, STR_BNK_UNDEF"\n", prog);
free(instr);
return false;
}
opl3_chip *chip = OPL3_Alloc(samplerate, 2);
bank_handle *bank = bank_alloc(chip, instr, 0, 0, 0);
aud_handle dev;
if(aud_open_dev(&dev, device, samplerate, 2, fsize, bufsize, widefmt) ^ 1) {
free(instr);
free(chip);
free(bank);
return false;
}
samplerate = dev.samplerate;
OPL3_Rate(chip, samplerate);
bool played = false;
if(offset != 256) {
for(int z = offset; z < 256; z++) {
played |= tst_note(&dev, instr, chip, bank, samplerate, z, note, len, pause);
}
}
else {
played = tst_note(&dev, instr, chip, bank, samplerate, prog, note, len, pause);
}
if(played ^ 1) {
fprintf(stderr, STR_BNK_NONE"\n");
}
aud_flush(&dev);
aud_close(&dev);
free(instr);
free(chip);
free(bank);
return played;
}
int main(int argc, char **argv) {
int32_t samplerate = 48000;
char *device = "default";
int32_t bufsize = 0;
int32_t fsize = 32;
int32_t widefmt = 0;
char *dmxname = NULL;
char *drumname = NULL;
int32_t usedrum = 0;
int32_t prog = 256;
int32_t dprog = 256;
int32_t mprog = 256;
int32_t note = 36;
int32_t len = 750;
int32_t pause = 250;
int32_t offset = 256;
argp_t *argspec = arg_alloc(15);
arg_add_nstr(argspec, STR_ARGS_BANK, true, &dmxname);
arg_add_nint(argspec, STR_ARGS_OFFSET, false, 0, 255, &offset);
arg_add_int(argspec, 'r', STR_ARGS_SRATE, 8000, 384000, &samplerate);
arg_add_str(argspec, 'd', STR_ARGS_DEVICE, &device);
arg_add_int(argspec, 'b', STR_ARGS_BUFFER, 0, 1048576, &bufsize);
arg_add_int(argspec, 'f', STR_ARGS_FRAMES, 2, 8192, &fsize);
arg_add_bool(argspec, 'w', STR_ARGS_WIDEFT, &widefmt);
arg_add_int(argspec, 'n', STR_ARGS_NOTE, 0, 127, &note);
arg_add_int(argspec, 'l', STR_ARGS_LENGTH, 10, 60000, &len);
arg_add_int(argspec, 'p', STR_ARGS_PAUSE, 10, 60000, &pause);
arg_add_int(argspec, 'i', STR_ARGS_INSTR, 0, 255, &prog);
arg_add_int(argspec, 'm', STR_ARGS_PERC, 0, 127, &mprog);
arg_add_int(argspec, 'g', STR_ARGS_DPERC, 0, 46, &dprog);
arg_add_str(argspec, 'q', STR_ARGS_DBANK, &drumname);
arg_add_bool(argspec, 'Q', STR_ARGS_USEDRM, &usedrum);
if(arg_parse(argspec, argc, argv) ^ 1) {
return 1;
}
if(dprog != 256) {
if((prog != 256) || (mprog != 256)) {
fprintf(stderr, STR_TST_NDDRUM"\n");
return 1;
}
prog = dprog + 128 + 35;
}
else if(mprog != 256) {
if((prog != 256) || (dprog != 256)) {
fprintf(stderr, STR_TST_NMDRUM"\n");
return 1;
}
prog = mprog + 128;
}
if((offset != 256) && (prog != 256)) {
fprintf(stderr, STR_TST_NOFFS"\n");
return 1;
}
else if((offset == 256) && (prog == 256)) {
offset = 0;
}
if(tst_play(samplerate, dmxname, drumname, usedrum, device, fsize, bufsize, widefmt, prog, note, offset, len, pause) ^ 1) {
return 1;
}
return 0;
}