123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #include "Precompiled.h"
- #include "globaldata.h"
- #include <assert.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "idlib/sys/sys_defines.h"
- unsigned long ReadVarLen( char* buffer ) {
- unsigned long value;
- byte c;
- if ((value = *buffer++) & 0x80) {
- value &= 0x7f;
- do {
- value = (value << 7) + ((c = *buffer++) & 0x7f);
- } while (c & 0x80);
- }
- return value;
- }
- int WriteVarLen( long value, byte* out )
- {
- long buffer, count = 0;
- buffer = value & 0x7f;
- while ((value >>= 7) > 0) {
- buffer <<= 8;
- buffer += 0x80;
- buffer += (value & 0x7f);
- }
- while (1) {
- ++count;
- *out = (byte)buffer;
- ++out;
- if (buffer & 0x80)
- buffer >>= 8;
- else
- break;
- }
- return count;
- }
- unsigned char* WriteByte(void* buf, byte b)
- {
- unsigned char* buffer = (unsigned char*)buf;
- *buffer++ = b;
- return buffer;
- }
- unsigned char* WriteShort(void* b, unsigned short s)
- {
- unsigned char* buffer = (unsigned char*)b;
- *buffer++ = (s >> 8);
- *buffer++ = (s & 0x00FF);
- return buffer;
- }
- unsigned char* WriteInt(void* b, unsigned int i)
- {
- unsigned char* buffer = (unsigned char*)b;
- *buffer++ = (i & 0xff000000) >> 24;
- *buffer++ = (i & 0x00ff0000) >> 16;
- *buffer++ = (i & 0x0000ff00) >> 8;
- *buffer++ = (i & 0x000000ff);
- return buffer;
- }
- void Midi_CreateHeader(MidiHeaderChunk_t* header, short format, short track_count, short division)
- {
- WriteInt(header->name, 'MThd');
- WriteInt(&header->length, 6);
- WriteShort(&header->format, format);
- WriteShort(&header->ntracks, track_count);
- WriteShort(&header->division, division);
- }
- unsigned char* Midi_WriteTempo(unsigned char* buffer, int tempo)
- {
- buffer = WriteByte(buffer, 0x00);
- buffer = WriteByte(buffer, 0xff);
- buffer = WriteShort(buffer, 0x5103);
-
- buffer = WriteByte(buffer, tempo & 0x000000ff);
- buffer = WriteByte(buffer, (tempo & 0x0000ff00) >> 8);
- buffer = WriteByte(buffer, (tempo & 0x00ff0000) >> 16);
- return buffer;
- }
- int Midi_UpdateBytesWritten(int* bytes_written, int to_add, int max)
- {
- *bytes_written += to_add;
- if (max && *bytes_written > max)
- {
- assert(0);
- return 0;
- }
- return 1;
- }
- unsigned char MidiMap[] =
- {
- 0,
- 0,
- 1,
- 0x07,
- 0x0A,
- 0x0B,
- 0x5B,
- 0x5D,
- 0x40,
- 0x43,
- 0x78,
- 0x7B,
- 0x7E,
- 0x7F,
- 0x79,
- };
- namespace {
- unsigned short LittleToNative( const unsigned short value ) {
- return value;
- }
- }
- int Mus2Midi(unsigned char* bytes, unsigned char* out, int* len)
- {
-
- MUSheader_t header;
-
-
- unsigned char* cur = bytes,* end;
-
- MidiHeaderChunk_t midiHeader;
-
- MidiTrackChunk_t midiTrackHeader;
-
- byte* midiTrackHeaderOut;
-
-
- int delta_time = 0;
- int temp;
- int channel_volume[MIDI_MAXCHANNELS] = {0};
- int bytes_written = 0;
- int channelMap[MIDI_MAXCHANNELS], currentChannel = 0;
- byte last_status = 0;
-
- memcpy(&header, cur, sizeof(header));
- cur += sizeof(header);
- header.scoreLen = LittleToNative( header.scoreLen );
- header.scoreStart = LittleToNative( header.scoreStart );
- header.channels = LittleToNative( header.channels );
- header.sec_channels = LittleToNative( header.sec_channels );
- header.instrCnt = LittleToNative( header.instrCnt );
- header.dummy = LittleToNative( header.dummy );
-
-
- if (header.channels > MIDI_MAXCHANNELS - 1)
- return 0;
-
- for (temp = 0; temp < MIDI_MAXCHANNELS; ++temp) {
- channelMap[temp] = -1;
- channel_volume[temp] = 0x40;
- }
- channelMap[15] = 9;
-
- cur = bytes + header.scoreStart;
- end = cur + header.scoreLen;
-
- Midi_CreateHeader(&midiHeader, 0, 1, 0x0059);
- Midi_UpdateBytesWritten(&bytes_written, MIDIHEADERSIZE, *len);
- memcpy(out, &midiHeader, MIDIHEADERSIZE);
- out += MIDIHEADERSIZE;
-
-
- Midi_UpdateBytesWritten(&bytes_written, sizeof(midiTrackHeader), *len);
- midiTrackHeaderOut = out;
- out += sizeof(midiTrackHeader);
-
-
- Midi_UpdateBytesWritten(&bytes_written, 7, *len);
- out = Midi_WriteTempo(out, 0x001aa309);
-
-
- Midi_UpdateBytesWritten(&bytes_written, 4, *len);
- out = WriteByte(out, 0x00);
- out = WriteByte(out, 0xB9);
- out = WriteByte(out, 0x07);
- out = WriteByte(out, 127);
-
-
- while (cur < end) {
- byte channel;
- byte event;
- byte temp_buffer[32];
- byte *out_local = temp_buffer;
- byte status, bit1, bit2, bitc = 2;
-
-
- event = *cur++;
- channel = (event & 15);
-
-
- out_local += WriteVarLen(delta_time, out_local);
-
- if (channelMap[channel] < 0) {
-
- out_local = WriteByte(out_local, 0xB0 + currentChannel);
- out_local = WriteByte(out_local, 0x07);
- out_local = WriteByte(out_local, 127);
- out_local = WriteByte(out_local, 0x00);
- channelMap[channel] = currentChannel++;
- if (currentChannel == 9)
- ++currentChannel;
- }
- status = channelMap[channel];
-
- switch ((event & 122) >> 4)
- {
- default:
- assert(0);
- break;
- case MUSEVENT_KEYOFF:
- status |= 0x80;
- bit1 = *cur++;
- bit2 = 0x40;
- break;
- case MUSEVENT_KEYON:
- status |= 0x90;
- bit1 = *cur & 127;
- if (*cur++ & 128)
- channel_volume[channelMap[channel]] = *cur++;
- bit2 = channel_volume[channelMap[channel]];
- break;
- case MUSEVENT_PITCHWHEEL:
- status |= 0xE0;
- bit1 = (*cur & 1) >> 6;
- bit2 = (*cur++ >> 1) & 127;
- break;
- case MUSEVENT_CHANNELMODE:
- status |= 0xB0;
- assert(*cur < sizeof(MidiMap) / sizeof(MidiMap[0]));
- bit1 = MidiMap[*cur++];
- bit2 = (*cur++ == 12) ? header.channels + 1 : 0x00;
- break;
- case MUSEVENT_CONTROLLERCHANGE:
- if (*cur == 0) {
- cur++;
- status |= 0xC0;
- bit1 = *cur++;
- bitc = 1;
- } else {
- status |= 0xB0;
- assert(*cur < sizeof(MidiMap) / sizeof(MidiMap[0]));
- bit1 = MidiMap[*cur++];
- bit2 = *cur++;
- }
- break;
- case 5:
- assert(0);
- break;
- case MUSEVENT_END:
- status = 0xff;
- bit1 = 0x2f;
- bit2 = 0x00;
- assert(cur == end);
- break;
- case 7:
- assert(0);
- break;
- }
-
- out_local = WriteByte(out_local, status);
- out_local = WriteByte(out_local, bit1);
- if (bitc == 2)
- out_local = WriteByte(out_local, bit2);
-
-
- if (out_local != temp_buffer)
- {
- Midi_UpdateBytesWritten(&bytes_written, out_local - temp_buffer, *len);
- memcpy(out, temp_buffer, out_local - temp_buffer);
- out += out_local - temp_buffer;
- }
- if (event & 128) {
- delta_time = 0;
- do {
- delta_time = delta_time * 128 + (*cur & 127);
- } while ((*cur++ & 128));
- } else {
- delta_time = 0;
- }
- }
-
- WriteInt(midiTrackHeader.name, 'MTrk');
- WriteInt(&midiTrackHeader.length, out - midiTrackHeaderOut - sizeof(midiTrackHeader));
- memcpy(midiTrackHeaderOut, &midiTrackHeader, sizeof(midiTrackHeader));
-
-
- *len = bytes_written;
-
- return 1;
- }
|