2020-12-02 18:12:34 +01:00
|
|
|
#include "pch.h"
|
|
|
|
#include "midi.h"
|
|
|
|
|
2021-02-15 16:55:54 +01:00
|
|
|
|
|
|
|
#include "pb.h"
|
2021-01-23 11:33:30 +01:00
|
|
|
#include "pinball.h"
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
Mix_Music* midi::currentMidi;
|
2021-01-23 11:33:30 +01:00
|
|
|
|
2020-12-02 18:12:34 +01:00
|
|
|
MCIERROR midi::play_pb_theme(int flag)
|
|
|
|
{
|
2021-02-15 16:55:54 +01:00
|
|
|
if (pb::FullTiltMode)
|
|
|
|
{
|
|
|
|
return play_ft(track1);
|
|
|
|
}
|
|
|
|
|
2021-01-23 11:33:30 +01:00
|
|
|
MCIERROR result = 0;
|
|
|
|
music_stop();
|
2021-08-27 12:29:41 +02:00
|
|
|
if (currentMidi)
|
|
|
|
result = Mix_PlayMusic(currentMidi, -1);
|
|
|
|
|
2021-01-23 11:33:30 +01:00
|
|
|
return result;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
MCIERROR midi::music_stop()
|
|
|
|
{
|
2021-02-15 16:55:54 +01:00
|
|
|
if (pb::FullTiltMode)
|
|
|
|
{
|
|
|
|
return stop_ft();
|
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
|
|
|
|
return Mix_HaltMusic();
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int midi::music_init(HWND hwnd)
|
|
|
|
{
|
2021-02-15 16:55:54 +01:00
|
|
|
if (pb::FullTiltMode)
|
|
|
|
{
|
|
|
|
return music_init_ft(hwnd);
|
|
|
|
}
|
2021-08-27 12:29:41 +02:00
|
|
|
|
|
|
|
currentMidi = Mix_LoadMUS(pinball::get_rc_string(156, 0));
|
|
|
|
return currentMidi != nullptr;
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
|
|
|
|
2021-02-16 17:03:45 +01:00
|
|
|
MCIERROR midi::restart_midi_seq(LPARAM param)
|
2020-12-02 18:12:34 +01:00
|
|
|
{
|
2021-02-15 16:55:54 +01:00
|
|
|
if (pb::FullTiltMode)
|
|
|
|
{
|
|
|
|
return play_ft(active_track);
|
|
|
|
}
|
|
|
|
|
2021-01-23 11:33:30 +01:00
|
|
|
MCIERROR result = 0;
|
2021-08-27 12:29:41 +02:00
|
|
|
music_stop();
|
|
|
|
if (currentMidi)
|
|
|
|
result = Mix_PlayMusic(currentMidi, -1);
|
2021-01-23 11:33:30 +01:00
|
|
|
|
|
|
|
return result;
|
2020-12-04 16:35:47 +01:00
|
|
|
}
|
|
|
|
|
2021-01-23 11:33:30 +01:00
|
|
|
void midi::music_shutdown()
|
2020-12-04 16:35:47 +01:00
|
|
|
{
|
2021-02-15 16:55:54 +01:00
|
|
|
if (pb::FullTiltMode)
|
|
|
|
{
|
|
|
|
music_shutdown_ft();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
Mix_FreeMusic(currentMidi);
|
2020-12-02 18:12:34 +01:00
|
|
|
}
|
2021-02-15 16:55:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
objlist_class<midi_struct>* midi::TrackList;
|
|
|
|
midi_struct *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::active_track2;
|
|
|
|
int midi::some_flag1;
|
|
|
|
|
|
|
|
int midi::music_init_ft(HWND hwnd)
|
|
|
|
{
|
|
|
|
active_track = nullptr;
|
|
|
|
TrackList = new objlist_class<midi_struct>(0, 1);
|
|
|
|
|
|
|
|
track1 = load_track("taba1");
|
|
|
|
track2 = load_track("taba2");
|
|
|
|
track3 = load_track("taba3");
|
|
|
|
if (!track2)
|
|
|
|
track2 = track1;
|
|
|
|
if (!track3)
|
|
|
|
track3 = track1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void midi::music_shutdown_ft()
|
|
|
|
{
|
|
|
|
if (active_track)
|
|
|
|
stream_close(active_track);
|
|
|
|
while (TrackList->GetCount())
|
|
|
|
{
|
|
|
|
midi_struct* midi = TrackList->Get(0);
|
|
|
|
unload_track(midi);
|
|
|
|
TrackList->Delete(midi);
|
|
|
|
}
|
|
|
|
active_track = nullptr;
|
|
|
|
delete TrackList;
|
|
|
|
}
|
|
|
|
|
|
|
|
midi_struct* midi::load_track(LPCSTR fileName)
|
|
|
|
{
|
|
|
|
midi_struct* midi;
|
|
|
|
char filePath[256];
|
|
|
|
char fileName2[256];
|
|
|
|
|
|
|
|
lstrcpyA(fileName2, "sound\\");
|
|
|
|
lstrcatA(fileName2, fileName);
|
|
|
|
pinball::make_path_name(filePath, fileName2, 254u);
|
|
|
|
lstrcatA(filePath, ".MDS");
|
|
|
|
if (load_file(&midi, filePath, 0, 1))
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
if (midi)
|
|
|
|
TrackList->Add(midi);
|
|
|
|
return midi;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags)
|
|
|
|
{
|
|
|
|
int returnCode;
|
|
|
|
unsigned int fileSize;
|
|
|
|
HANDLE mapHandle = nullptr;
|
|
|
|
midi_struct* midi = nullptr;
|
|
|
|
HANDLE fileHandle = INVALID_HANDLE_VALUE;
|
|
|
|
int fileFlag = 0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ((flags & 3) == 0 || (flags & 3) == 3)
|
|
|
|
{
|
|
|
|
returnCode = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
midi = static_cast<midi_struct*>(LocalAlloc(0x40u, sizeof(midi_struct)));
|
|
|
|
if (!midi)
|
|
|
|
{
|
|
|
|
returnCode = 1;
|
|
|
|
break;
|
|
|
|
}
|
2021-02-18 10:53:25 +01:00
|
|
|
midi->Magic = mmioFOURCC('M', 'D', 'S', 'I');
|
2021-02-15 16:55:54 +01:00
|
|
|
midi->StreamHandle = nullptr;
|
|
|
|
midi->PreparedBlocksCount = 0;
|
|
|
|
|
|
|
|
if ((flags & 2) != 0)
|
|
|
|
{
|
|
|
|
fileSize = fileSizeP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fileFlag = 1;
|
|
|
|
fileHandle = CreateFileA(static_cast<LPCSTR>(filePtrOrPath), GENERIC_READ, 1u, nullptr, OPEN_EXISTING,
|
|
|
|
0x80u, nullptr);
|
|
|
|
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
returnCode = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileSize = GetFileSize(fileHandle, nullptr);
|
|
|
|
mapHandle = CreateFileMappingA(fileHandle, nullptr, 2u, 0, 0, nullptr);
|
|
|
|
if (!mapHandle)
|
|
|
|
{
|
|
|
|
returnCode = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
filePtrOrPath = MapViewOfFile(mapHandle, 4u, 0, 0, 0);
|
|
|
|
if (!filePtrOrPath)
|
|
|
|
{
|
|
|
|
returnCode = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
returnCode = read_file(midi, static_cast<riff_header*>(filePtrOrPath), fileSize);
|
|
|
|
}
|
|
|
|
while (false);
|
|
|
|
|
|
|
|
|
|
|
|
if (returnCode)
|
|
|
|
{
|
|
|
|
if (midi)
|
|
|
|
LocalFree(midi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*midi_res = midi;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fileFlag)
|
|
|
|
{
|
|
|
|
if (filePtrOrPath)
|
|
|
|
UnmapViewOfFile(filePtrOrPath);
|
|
|
|
if (mapHandle)
|
|
|
|
CloseHandle(mapHandle);
|
|
|
|
if (fileHandle != INVALID_HANDLE_VALUE)
|
|
|
|
CloseHandle(fileHandle);
|
|
|
|
}
|
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::read_file(midi_struct* midi, riff_header* filePtr, unsigned fileSize)
|
|
|
|
{
|
|
|
|
auto returnCode = 0;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
midi->DataPtr1 = nullptr;
|
|
|
|
if (fileSize < 12)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
2021-02-18 10:53:25 +01:00
|
|
|
if (filePtr->Riff != mmioFOURCC('R', 'I', 'F', 'F'))
|
2021-02-15 16:55:54 +01:00
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
2021-02-18 10:53:25 +01:00
|
|
|
if (filePtr->Mids != mmioFOURCC('M', 'I', 'D', 'S'))
|
2021-02-15 16:55:54 +01:00
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (filePtr->FileSize > fileSize - 8)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (fileSize - 12 < 8)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
2021-02-18 10:53:25 +01:00
|
|
|
if (filePtr->Fmt != mmioFOURCC('f', 'm', 't', ' '))
|
2021-02-15 16:55:54 +01:00
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (filePtr->FmtSize > fileSize - 12)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (filePtr->FmtSize < 12)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
midi->DwTimeFormat = filePtr->dwTimeFormat;
|
|
|
|
midi->CbMaxBuffer = filePtr->cbMaxBuffer;
|
|
|
|
midi->DwFlagsFormat = filePtr->dwFlags;
|
|
|
|
auto blocksSize = fileSize - 20 - filePtr->FmtSize;
|
|
|
|
if (blocksSize < 8)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto dataChunk = reinterpret_cast<riff_data*>(reinterpret_cast<char*>(&filePtr->dwTimeFormat) + filePtr->FmtSize
|
|
|
|
);
|
2021-02-18 10:53:25 +01:00
|
|
|
if (dataChunk->Data != mmioFOURCC('d','a','t','a'))
|
2021-02-15 16:55:54 +01:00
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (dataChunk->DataSize > blocksSize || dataChunk->DataSize < 4)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
midi->BlockCount = dataChunk->BlocksPerChunk;
|
2021-02-18 10:53:25 +01:00
|
|
|
midi->DataPtr1 = reinterpret_cast<midihdr_tag*>(memory::allocate(
|
|
|
|
dataChunk->BlocksPerChunk * (midi->CbMaxBuffer + sizeof(midihdr_tag))));
|
2021-02-15 16:55:54 +01:00
|
|
|
if (!midi->DataPtr1)
|
|
|
|
{
|
|
|
|
returnCode = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!midi->BlockCount)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto blocksSizeIndex = blocksSize - 12;
|
|
|
|
auto srcPtr = dataChunk->Blocks;
|
|
|
|
auto* dstPtr = midi->DataPtr1;
|
|
|
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
|
|
|
{
|
|
|
|
dstPtr->lpData = reinterpret_cast<LPSTR>(&dstPtr[1]);
|
|
|
|
dstPtr->dwBufferLength = midi->CbMaxBuffer;
|
|
|
|
dstPtr->dwFlags = 0;
|
|
|
|
dstPtr->dwUser = reinterpret_cast<DWORD_PTR>(midi);
|
|
|
|
dstPtr->lpNext = nullptr;
|
|
|
|
if (blocksSizeIndex < 8)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto blockSize = srcPtr->CbBuffer;
|
|
|
|
if (blockSize > midi->CbMaxBuffer || blockSize > blocksSizeIndex - 8)
|
|
|
|
{
|
|
|
|
returnCode = 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((midi->DwFlagsFormat & 1) != 0)
|
|
|
|
{
|
|
|
|
/*Not used in FT, some kind of compression*/
|
|
|
|
assertm(false, "Unimplemented code reached");
|
|
|
|
/*int a1[16];
|
|
|
|
a1[0] = (int)blockDataPtr;
|
|
|
|
a1[2] = blockSize;
|
|
|
|
a1[1] = blockSize;
|
|
|
|
if (!sub_4031A0(a1, dataPtr))
|
|
|
|
{
|
|
|
|
returnCode = 3; break;
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dstPtr->dwBytesRecorded = blockSize;
|
|
|
|
memcpy(dstPtr->lpData, srcPtr->AData, blockSize);
|
|
|
|
}
|
|
|
|
blocksSizeIndex -= blockSize + 8;
|
|
|
|
srcPtr = reinterpret_cast<riff_block*>(&srcPtr->AData[blockSize]);
|
|
|
|
dstPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&dstPtr[1]) + midi->CbMaxBuffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (false);
|
|
|
|
|
|
|
|
if (returnCode && midi->DataPtr1)
|
|
|
|
{
|
2021-02-18 10:53:25 +01:00
|
|
|
memory::free(midi->DataPtr1);
|
2021-02-15 16:55:54 +01:00
|
|
|
}
|
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::play_ft(midi_struct* midi)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
stop_ft();
|
|
|
|
if (!midi)
|
|
|
|
return 0;
|
|
|
|
if (some_flag1)
|
|
|
|
{
|
|
|
|
active_track2 = midi;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (stream_open(midi, 1))
|
|
|
|
{
|
|
|
|
active_track = nullptr;
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
active_track = midi;
|
|
|
|
result = 1;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::stop_ft()
|
|
|
|
{
|
|
|
|
int returnCode = 0;
|
|
|
|
if (active_track)
|
|
|
|
returnCode = stream_close(active_track);
|
|
|
|
active_track = nullptr;
|
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::unload_track(midi_struct* midi)
|
|
|
|
{
|
2021-02-18 10:53:25 +01:00
|
|
|
if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
2021-02-15 16:55:54 +01:00
|
|
|
return 6;
|
|
|
|
if (midi->StreamHandle)
|
|
|
|
stream_close(midi);
|
|
|
|
if (midi->DataPtr1)
|
|
|
|
{
|
2021-02-18 10:53:25 +01:00
|
|
|
memory::free(midi->DataPtr1);
|
2021-02-15 16:55:54 +01:00
|
|
|
}
|
2021-02-18 10:53:25 +01:00
|
|
|
midi->Magic = mmioFOURCC('d','a','t','a');
|
2021-02-15 16:55:54 +01:00
|
|
|
LocalFree(midi);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::stream_open(midi_struct* midi, char flags)
|
|
|
|
{
|
|
|
|
auto returnCode = 0;
|
2021-02-18 10:53:25 +01:00
|
|
|
if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
2021-02-15 16:55:54 +01:00
|
|
|
return 6;
|
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
/*UINT puDeviceID = -1;
|
2021-02-15 16:55:54 +01:00
|
|
|
auto steamOpenedFg = !midi->StreamHandle;
|
|
|
|
MIDIPROPTIMEDIV propdata{8, midi->DwTimeFormat};
|
|
|
|
if (steamOpenedFg &&
|
|
|
|
!midiStreamOpen(&midi->StreamHandle, &puDeviceID, 1u, reinterpret_cast<DWORD_PTR>(midi_callback), 0,
|
|
|
|
CALLBACK_FUNCTION) &&
|
|
|
|
!midiStreamProperty(midi->StreamHandle, reinterpret_cast<LPBYTE>(&propdata),MIDIPROP_TIMEDIV | MIDIPROP_SET))
|
|
|
|
{
|
|
|
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
|
|
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
|
|
|
{
|
|
|
|
if (midiOutPrepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR)) ||
|
|
|
|
midiStreamOut(midi->StreamHandle, blockPtr, sizeof(MIDIHDR)))
|
|
|
|
{
|
|
|
|
returnCode = 5;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
++midi->PreparedBlocksCount;
|
|
|
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!returnCode)
|
|
|
|
{
|
|
|
|
if (!steamOpenedFg && (midi->SomeFlag2 & 4) == 0)
|
|
|
|
return 7;
|
|
|
|
|
|
|
|
midi->SomeFlag2 &= ~2;
|
|
|
|
if ((flags & 1) != 0)
|
|
|
|
midi->SomeFlag2 |= 2;
|
|
|
|
midi->SomeFlag2 &= ~4;
|
|
|
|
if (midiStreamRestart(midi->StreamHandle))
|
|
|
|
returnCode = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (returnCode && steamOpenedFg)
|
|
|
|
{
|
|
|
|
if (midi->StreamHandle)
|
|
|
|
stream_close(midi);
|
2021-08-27 12:29:41 +02:00
|
|
|
}*/
|
2021-02-15 16:55:54 +01:00
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
int midi::stream_close(midi_struct* midi)
|
|
|
|
{
|
2021-08-27 12:29:41 +02:00
|
|
|
int returnCode = 0;
|
2021-02-15 16:55:54 +01:00
|
|
|
|
2021-08-27 12:29:41 +02:00
|
|
|
/*if (midi->Magic != mmioFOURCC('M', 'D', 'S', 'I'))
|
2021-02-15 16:55:54 +01:00
|
|
|
return 6;
|
|
|
|
if (!midi->StreamHandle)
|
|
|
|
return 7;
|
|
|
|
midi->SomeFlag2 |= 1u;
|
|
|
|
if (midiOutReset(reinterpret_cast<HMIDIOUT>(midi->StreamHandle)))
|
|
|
|
{
|
|
|
|
returnCode = 5;
|
|
|
|
midi->SomeFlag2 &= ~1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
|
|
|
for (int i = midi->BlockCount; i; --i)
|
|
|
|
{
|
|
|
|
midiOutUnprepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR));
|
|
|
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
|
|
|
}
|
|
|
|
midiStreamClose(midi->StreamHandle);
|
|
|
|
returnCode = 0;
|
|
|
|
midi->StreamHandle = nullptr;
|
|
|
|
midi->SomeFlag2 = 0;
|
2021-08-27 12:29:41 +02:00
|
|
|
}*/
|
2021-02-15 16:55:54 +01:00
|
|
|
return returnCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void midi::midi_callback(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
|
|
|
{
|
|
|
|
if (wMsg == 969)
|
|
|
|
{
|
|
|
|
auto mhdr = reinterpret_cast<LPMIDIHDR>(dwParam1);
|
|
|
|
auto midi = reinterpret_cast<midi_struct*>(mhdr->dwUser);
|
2021-08-27 12:29:41 +02:00
|
|
|
/*if ((midi->SomeFlag2 & 2) == 0 || (midi->SomeFlag2 & 1) != 0 || midiStreamOut(
|
2021-02-15 16:55:54 +01:00
|
|
|
midi->StreamHandle, mhdr, sizeof(MIDIHDR)))
|
2021-08-27 12:29:41 +02:00
|
|
|
--midi->PreparedBlocksCount;*/
|
2021-02-15 16:55:54 +01:00
|
|
|
}
|
|
|
|
}
|