Changes for 1 global capture directory
Support for capturing raw midi Support for capturing raw opl Slight rewrite of the midi output classes Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1865
This commit is contained in:
parent
dc6e126a71
commit
a18b3cafd0
5 changed files with 126 additions and 57 deletions
132
src/gui/midi.cpp
132
src/gui/midi.cpp
|
@ -24,8 +24,12 @@
|
|||
#include "cross.h"
|
||||
#include "support.h"
|
||||
#include "setup.h"
|
||||
#include "mapper.h"
|
||||
#include "pic.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define SYSEX_SIZE 1024
|
||||
#define RAWBUF 1024
|
||||
|
||||
Bit8u MIDI_evt_len[256] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00
|
||||
|
@ -47,7 +51,7 @@ Bit8u MIDI_evt_len[256] = {
|
|||
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0
|
||||
|
||||
0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0
|
||||
0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,1 // 0xf0
|
||||
};
|
||||
|
||||
class MidiHandler;
|
||||
|
@ -62,7 +66,7 @@ public:
|
|||
};
|
||||
virtual bool Open(const char * conf) { return true; };
|
||||
virtual void Close(void) {};
|
||||
virtual void PlayMsg(Bit32u msg) {};
|
||||
virtual void PlayMsg(Bit8u * msg) {};
|
||||
virtual void PlaySysex(Bit8u * sysex,Bitu len) {};
|
||||
virtual char * GetName(void) { return "none"; };
|
||||
MidiHandler * next;
|
||||
|
@ -96,49 +100,117 @@ static struct {
|
|||
Bitu status;
|
||||
Bitu cmd_len;
|
||||
Bitu cmd_pos;
|
||||
|
||||
Bit32u cmd_msg;
|
||||
Bit8u data[4];
|
||||
Bit8u cmd_buf[8];
|
||||
struct {
|
||||
Bit8u buf[SYSEX_SIZE];
|
||||
Bitu used;
|
||||
bool active;
|
||||
} sysex;
|
||||
bool available;
|
||||
MidiHandler * handler;
|
||||
struct {
|
||||
FILE * handle;
|
||||
Bit8u buffer[RAWBUF+SYSEX_SIZE];
|
||||
Bitu used,done;
|
||||
Bit32u last;
|
||||
} raw;
|
||||
} midi;
|
||||
|
||||
static Bit8u midi_header[]={
|
||||
'M','T','h','d', /* Bit32u, Header Chunk */
|
||||
0x0,0x0,0x0,0x6, /* Bit32u, Chunk Length */
|
||||
0x0,0x0, /* Bit16u, Format, 0=single track */
|
||||
0x0,0x1, /* Bit16u, Track Count, 1 track */
|
||||
0x01,0xf4, /* Bit16u, Timing, 2 beats/second with 500 frames */
|
||||
'M','T','r','k', /* Bit32u, Track Chunk */
|
||||
0x0,0x0,0x0,0x0, /* Bit32u, Chunk Length */
|
||||
//Track data
|
||||
};
|
||||
|
||||
#define ADDBUF(_VAL_) midi.raw.buffer[midi.raw.used++]=(Bit8u)(_VAL_);
|
||||
static INLINE void RawAddNumber(Bit32u val) {
|
||||
if (val & 0xfe00000) ADDBUF(0x80|((val >> 21) & 0x7f));
|
||||
if (val & 0xfffc000) ADDBUF(0x80|((val >> 14) & 0x7f));
|
||||
if (val & 0xfffff80) ADDBUF(0x80|((val >> 7) & 0x7f));
|
||||
ADDBUF(val & 0x7f);
|
||||
}
|
||||
static INLINE void RawAddDelta(void) {
|
||||
if (!midi.raw.last) midi.raw.last=PIC_Ticks;
|
||||
Bit32u delta=PIC_Ticks-midi.raw.last;
|
||||
midi.raw.last=PIC_Ticks;
|
||||
RawAddNumber(delta);
|
||||
}
|
||||
|
||||
static INLINE void RawAddData(Bit8u * data,Bitu len) {
|
||||
for (Bitu i=0;i<len;i++) ADDBUF(data[i]);
|
||||
if (midi.raw.used>=RAWBUF) {
|
||||
fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle);
|
||||
midi.raw.done+=midi.raw.used;
|
||||
midi.raw.used=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void MIDI_SaveRawEvent(void) {
|
||||
/* Check for previously opened wave file */
|
||||
if (midi.raw.handle) {
|
||||
LOG_MSG("Stopping raw midi saving.");
|
||||
ADDBUF(0x00);//Delta time
|
||||
ADDBUF(0xff);ADDBUF(0x2F);ADDBUF(0x00); //End of track event
|
||||
fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle);
|
||||
midi.raw.done+=midi.raw.used;
|
||||
fseek(midi.raw.handle,18, SEEK_SET);
|
||||
Bit8u size[4];
|
||||
size[0]=(Bit8u)(midi.raw.done >> 24);
|
||||
size[1]=(Bit8u)(midi.raw.done >> 16);
|
||||
size[2]=(Bit8u)(midi.raw.done >> 8);
|
||||
size[3]=(Bit8u)(midi.raw.done >> 0);
|
||||
fwrite(&size,1,4,midi.raw.handle);
|
||||
fclose(midi.raw.handle);
|
||||
midi.raw.handle=0;
|
||||
} else {
|
||||
midi.raw.handle=OpenCaptureFile("Raw Midi",".mid");
|
||||
if (!midi.raw.handle) return;
|
||||
fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle);
|
||||
midi.raw.used=0;
|
||||
midi.raw.done=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MIDI_RawOutByte(Bit8u data) {
|
||||
/* Test for a new status byte */
|
||||
if (midi.sysex.active && !(data&0x80)) {
|
||||
if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data;
|
||||
return;
|
||||
} else if (data&0x80) {
|
||||
if (midi.sysex.active) {
|
||||
/* Play a sysex message */
|
||||
/* Test for a active sysex tranfer */
|
||||
if (midi.status==0xf0) {
|
||||
if (!(data&0x80)) {
|
||||
if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data;
|
||||
return;
|
||||
} else {
|
||||
midi.sysex.buf[midi.sysex.used++]=0xf7;
|
||||
midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used);
|
||||
LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used);
|
||||
midi.sysex.active=false;
|
||||
if (data==0xf7) return;
|
||||
if (midi.raw.handle) {
|
||||
RawAddDelta();
|
||||
ADDBUF(0xf0);
|
||||
RawAddNumber(midi.sysex.used-1);
|
||||
RawAddData(&midi.sysex.buf[1],midi.sysex.used-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data&0x80) {
|
||||
midi.status=data;
|
||||
midi.cmd_pos=0;
|
||||
midi.cmd_msg=0;
|
||||
midi.cmd_len=MIDI_evt_len[data];
|
||||
if (midi.status==0xf0) {
|
||||
midi.sysex.active=true;
|
||||
midi.sysex.buf[0]=0xf0;
|
||||
midi.sysex.used=1;
|
||||
return;
|
||||
}
|
||||
midi.cmd_len=MIDI_evt_len[data];
|
||||
}
|
||||
midi.cmd_msg|=data << (8 * midi.cmd_pos);
|
||||
midi.cmd_pos++;
|
||||
if (midi.cmd_pos >= midi.cmd_len) {
|
||||
midi.handler->PlayMsg(midi.cmd_msg);
|
||||
midi.cmd_msg=midi.status;
|
||||
midi.cmd_pos=1;
|
||||
midi.cmd_buf[midi.cmd_pos++]=data;
|
||||
if (midi.cmd_len && midi.cmd_pos >= midi.cmd_len) {
|
||||
if (midi.raw.handle) {
|
||||
RawAddDelta();
|
||||
RawAddData(midi.cmd_buf,midi.cmd_len);
|
||||
}
|
||||
midi.handler->PlayMsg(midi.cmd_buf);
|
||||
midi.cmd_pos=1; //Use Running status
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,12 +218,21 @@ bool MIDI_Available(void) {
|
|||
return midi.available;
|
||||
}
|
||||
|
||||
static void MIDI_Stop(Section* sec) {
|
||||
if (midi.raw.handle) MIDI_SaveRawEvent();
|
||||
}
|
||||
|
||||
void MIDI_Init(Section * sec) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
const char * dev=section->Get_string("device");
|
||||
const char * conf=section->Get_string("config");
|
||||
/* If device = "default" go for first handler that works */
|
||||
MidiHandler * handler;
|
||||
MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI");
|
||||
sec->AddDestroyFunction(&MIDI_Stop);
|
||||
midi.status=0x00;
|
||||
midi.cmd_pos=0;
|
||||
midi.cmd_len=0;
|
||||
if (!strcasecmp(dev,"default")) goto getdefault;
|
||||
handler=handler_list;
|
||||
while (handler) {
|
||||
|
@ -180,6 +261,5 @@ getdefault:
|
|||
handler=handler->next;
|
||||
}
|
||||
/* This shouldn't be possible */
|
||||
midi.available=false;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: midi_alsa.h,v 1.7 2004-01-26 15:10:16 qbix79 Exp $ */
|
||||
/* $Id: midi_alsa.h,v 1.8 2004-07-04 21:08:08 harekiet Exp $ */
|
||||
|
||||
#define ALSA_PCM_OLD_HW_PARAMS_API
|
||||
#define ALSA_PCM_OLD_SW_PARAMS_API
|
||||
|
@ -75,45 +75,38 @@ public:
|
|||
send_event(1);
|
||||
}
|
||||
|
||||
void PlayMsg(Bit32u msg) {
|
||||
void PlayMsg(Bit8u * msg) {
|
||||
unsigned int midiCmd[4];
|
||||
ev.type = SND_SEQ_EVENT_OSS;
|
||||
|
||||
if (msg == 247) // to accomadate lure of the temptress
|
||||
return;
|
||||
ev.data.raw32.d[0] = msg[0];
|
||||
ev.data.raw32.d[1] = msg[1];
|
||||
ev.data.raw32.d[2] = msg[2];
|
||||
|
||||
midiCmd[3] = (msg & 0xFF000000) >> 24;
|
||||
midiCmd[2] = (msg & 0x00FF0000) >> 16;
|
||||
midiCmd[1] = (msg & 0x0000FF00) >> 8;
|
||||
midiCmd[0] = (msg & 0x000000FF);
|
||||
ev.data.raw32.d[0] = midiCmd[0];
|
||||
ev.data.raw32.d[1] = midiCmd[1];
|
||||
ev.data.raw32.d[2] = midiCmd[2];
|
||||
|
||||
unsigned char chanID = midiCmd[0] & 0x0F;
|
||||
switch (midiCmd[0] & 0xF0) {
|
||||
unsigned char chanID = msg[0] & 0x0F;
|
||||
switch (msg[0] & 0xF0) {
|
||||
case 0x80:
|
||||
snd_seq_ev_set_noteoff(&ev, chanID, midiCmd[1], midiCmd[2]);
|
||||
snd_seq_ev_set_noteoff(&ev, chanID, msg[1], msg[2]);
|
||||
send_event(1);
|
||||
break;
|
||||
case 0x90:
|
||||
snd_seq_ev_set_noteon(&ev, chanID, midiCmd[1], midiCmd[2]);
|
||||
snd_seq_ev_set_noteon(&ev, chanID, msg[1], msg[2]);
|
||||
send_event(1);
|
||||
break;
|
||||
case 0xB0:
|
||||
snd_seq_ev_set_controller(&ev, chanID, midiCmd[1], midiCmd[2]);
|
||||
snd_seq_ev_set_controller(&ev, chanID, msg[1], msg[2]);
|
||||
send_event(1);
|
||||
break;
|
||||
case 0xC0:
|
||||
snd_seq_ev_set_pgmchange(&ev, chanID, midiCmd[1]);
|
||||
snd_seq_ev_set_pgmchange(&ev, chanID, msg[1]);
|
||||
send_event(0);
|
||||
break;
|
||||
case 0xD0:
|
||||
snd_seq_ev_set_chanpress(&ev, chanID, midiCmd[1]);
|
||||
snd_seq_ev_set_chanpress(&ev, chanID, msg[1]);
|
||||
send_event(0);
|
||||
break;
|
||||
case 0xE0:{
|
||||
long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000;
|
||||
long theBend = ((long)msg[1] + (long)(msg[2] << 7)) - 0x2000;
|
||||
snd_seq_ev_set_pitchbend(&ev, chanID, theBend);
|
||||
send_event(1);
|
||||
}
|
||||
|
|
|
@ -76,12 +76,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void PlayMsg(Bit32u msg) {
|
||||
MusicDeviceMIDIEvent(m_musicDevice,
|
||||
(msg & 0x000000FF),
|
||||
(msg & 0x0000FF00) >> 8,
|
||||
(msg & 0x00FF0000) >> 16,
|
||||
0);
|
||||
void PlayMsg(Bit8u * msg) {
|
||||
MusicDeviceMIDIEvent(m_musicDevice,msg[0],msg[1],msg[2],0);
|
||||
}
|
||||
|
||||
void PlaySysex(Bit8u * sysex, Bitu len) {
|
||||
|
|
|
@ -45,15 +45,15 @@ public:
|
|||
if (!isOpen) return;
|
||||
if (device>0) close(device);
|
||||
};
|
||||
void PlayMsg(Bit32u msg) {
|
||||
void PlayMsg(Bit8u * msg) {
|
||||
Bit8u buf[128];Bitu pos=0;
|
||||
Bitu len=MIDI_evt_len[msg & 0xff];
|
||||
for (;len>0;len--) {
|
||||
buf[pos++] = SEQ_MIDIPUTC;
|
||||
buf[pos++] = msg & 0xff;
|
||||
buf[pos++] = *msg;
|
||||
buf[pos++] = device_num;
|
||||
buf[pos++] = 0;
|
||||
msg >>=8;
|
||||
msg++;
|
||||
}
|
||||
write(device,buf,pos);
|
||||
};
|
||||
|
|
|
@ -42,8 +42,8 @@ public:
|
|||
midiOutClose(m_out);
|
||||
CloseHandle (m_event);
|
||||
};
|
||||
void PlayMsg(Bit32u msg) {
|
||||
midiOutShortMsg(m_out, msg);
|
||||
void PlayMsg(Bit8u * msg) {
|
||||
midiOutShortMsg(m_out, *(Bit32u*)msg);
|
||||
};
|
||||
void PlaySysex(Bit8u * sysex,Bitu len) {
|
||||
if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) {
|
||||
|
|
Loading…
Add table
Reference in a new issue