www.pudn.com > gspmidi101src.zip > gspmidi.cpp
// gspmidi.cpp : DLL アプリケーション用のエントリ ポイントを定義します。
//
#include "gspmidi.h"
#include "config.h"
#include "output.h"
MAP_DEC_PLUGIN plugin;
extern "C" {
int open_midi_file(char* fn, int* duration, int* bitrate);
int start_play_midi();
int play_midi(int maxlen);
long seek_midi(long time);
void stop_play_midi();
void close_midi();
int read_config_file(char *name);
void free_instruments(void);
int GetSampleCount(int len);
#include "common.h"
WAVEHDR* g_pHdr = NULL;
extern PlayMode gsp_play_mode;
extern int free_instruments_afterwards;
extern int32 control_ratio;
extern int voices;
extern int32 amplification;
extern int adjust_panning_immediately;
extern int antialiasing_allowed;
};
void ReadRegistory();
void WriteRegistory();
void ShowConfigDialog(HWND hwndParent);
char g_szCopyright[256] = {0};
char g_szTrack[256] = {0};
HINSTANCE g_hInst = NULL;
BOOL g_fUpdateConfig = FALSE;
TCHAR g_szConfigFile[MAX_PATH] = {0};
int g_nSampleRate = 44100;
int g_nBitsPerSample = 16;
int g_nChannels = 2;
int g_nVoices = 32;
int g_nAmp = 80;
BOOL g_fAdjustPanning = FALSE;
BOOL g_fFreeInst = FALSE;
BOOL g_fAntialiasing = FALSE;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hInst = (HINSTANCE)hModule;
return TRUE;
}
BOOL ReadMidiText(LPCTSTR pszFile, LPSTR pszCopyright, LPSTR pszTrack)
{
//一番最初のトラックチャンクから著作権情報とトラック名を読み込む。
//バッファ > 0xFFであること
DWORD dwBuff;
DWORD dwRead;
HANDLE hFile;
if (pszCopyright)
pszCopyright[0] = '\0';
if (pszTrack)
pszTrack[0] = '\0';
hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
if (!ReadFile(hFile, &dwBuff, 4, &dwRead, NULL) || dwRead != 4 || dwBuff != 0x6468544d) {
CloseHandle(hFile);
return FALSE;
}
//トラックチャンクの検索
while (ReadFile(hFile, &dwBuff, 4, &dwRead, NULL) && dwRead == 4)
{
if (dwBuff == 0x6B72544D)
break;
SetFilePointer(hFile, -3, NULL, FILE_CURRENT);
}
if (dwBuff != 0x6B72544D) {
CloseHandle(hFile);
return FALSE;
}
SetFilePointer(hFile, 4, NULL, FILE_CURRENT);
while (ReadFile(hFile, &dwBuff, 4, &dwRead, NULL) && dwRead == 4)
{
if ((dwBuff & 0x0000FFFF) != 0x0000FF00 || dwBuff == 0x6B72544D)
break;
switch (dwBuff & 0x00FFFF00)
{
case 0x02FF00: //Copyright
dwBuff = (dwBuff&0xFF000000) >> 24;
if (pszCopyright && !strlen(pszCopyright)) {
ReadFile(hFile, pszCopyright, dwBuff, &dwRead, NULL);
*(pszCopyright + dwRead) = '\0';
}
else
SetFilePointer(hFile, dwBuff, NULL, FILE_CURRENT);
break;
case 0x03FF00: //Track
dwBuff = (dwBuff&0xFF000000) >> 24;
if (pszTrack && !strlen(pszTrack)) {
ReadFile(hFile, pszTrack, dwBuff, &dwRead, NULL);
*(pszTrack + dwRead) = '\0';
}
else
SetFilePointer(hFile, dwBuff, NULL, FILE_CURRENT);
break;
case 0x01FF00: //other text
case 0x04FF00: //Instrument
case 0x05FF00: //Lylics
case 0x06FF00: //Maker
case 0x07FF00: //Cue
default:
dwBuff = (dwBuff&0xFF000000) >> 24;
SetFilePointer(hFile, dwBuff, NULL, FILE_CURRENT);
break;
}
}
CloseHandle(hFile);
return TRUE;
}
void ResetConfig()
{
LPTSTR psz;
char szAnsi[MAX_PATH];
TCHAR szPath[MAX_PATH];
free_instruments();
gsp_play_mode.rate = g_nSampleRate;
control_ratio = gsp_play_mode.rate / 1000;
if (g_nBitsPerSample == 8)
gsp_play_mode.encoding &= ~PE_16BIT;
else
gsp_play_mode.encoding |= PE_16BIT;
if (g_nChannels == 2)
gsp_play_mode.encoding &= ~PE_MONO;
else
gsp_play_mode.encoding |= PE_MONO;
voices = g_nVoices;
amplification = g_nAmp;
adjust_panning_immediately = g_fAdjustPanning;
free_instruments_afterwards = g_fFreeInst;
antialiasing_allowed = g_fAntialiasing;
_tcscpy(szPath, g_szConfigFile);
psz = _tcsrchr(szPath, '\\');
if (psz) *psz = NULL;
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP, 0, szPath, -1, szAnsi, MAX_PATH, NULL, NULL);
#else
strcpy(szAnsi, szPath);
#endif
add_to_pathlist(szAnsi);
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP, 0, g_szConfigFile, -1, szAnsi, MAX_PATH, NULL, NULL);
#else
strcpy(szAnsi, g_szConfigFile);
#endif
read_config_file(szAnsi);
g_fUpdateConfig = FALSE;
}
////////////////////////////////////////////////////////////////////
// export functions
void WINAPI midiInit()
{
ReadRegistory();
ResetConfig();
}
void WINAPI midiQuit()
{
WriteRegistory();
}
DWORD WINAPI midiGetFunc()
{
return PLUGIN_FUNC_DECFILE | PLUGIN_FUNC_SEEKFILE | PLUGIN_FUNC_FILETAG;
}
BOOL WINAPI midiGetPluginName(LPTSTR pszName)
{
_tcscpy(pszName, _T("GreenSoftware MIDI plug-in"));
return TRUE;
}
int WINAPI midiGetFileExtCount()
{
return 1;
}
BOOL WINAPI midiGetFileExt(int nIndex, LPTSTR pszExt, LPTSTR pszExtDesc)
{
if (nIndex != 0)
return FALSE;
_tcscpy(pszExt, _T("mid"));
_tcscpy(pszExtDesc, _T("MIDI Files (*.mid)"));
return TRUE;
}
BOOL WINAPI midiSetEqualizer(MAP_PLUGIN_EQ* pEQ)
{
return FALSE;
}
BOOL WINAPI midiIsValidFile(LPCTSTR pszFile)
{
return TRUE;
}
void WINAPI midiShowConfigDlg(HWND hwndParent)
{
ShowConfigDialog(hwndParent);
}
BOOL WINAPI midiOpen(LPCTSTR pszFile, MAP_PLUGIN_FILE_INFO* pInfo)
{
char szFile[MAX_PATH];
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP, 0, pszFile, -1, szFile, MAX_PATH, 0, 0);
#else
strcpy(szFile, pszFile);
#endif
if (g_fUpdateConfig)
ResetConfig();
if (!open_midi_file(szFile, &pInfo->nDuration, &pInfo->nAvgBitrate))
return FALSE;
pInfo->nBitsPerSample = g_nBitsPerSample;
pInfo->nChannels = g_nChannels;
pInfo->nSampleRate = g_nSampleRate;
if (!pInfo->nAvgBitrate)
pInfo->nAvgBitrate = 1;
memset(g_szCopyright, 0, sizeof(g_szCopyright));
memset(g_szTrack, 0, sizeof(g_szTrack));
ReadMidiText(pszFile, g_szCopyright, g_szTrack);
return TRUE;
}
long WINAPI midiSeek(long lTime)
{
return seek_midi(lTime);
}
BOOL WINAPI midiStart()
{
return start_play_midi() ? TRUE : FALSE;
}
int WINAPI midiDecode(WAVEHDR* pHdr)
{
int nLen, nRet;
g_pHdr = pHdr;
nLen = GetSampleCount(pHdr->dwBufferLength - pHdr->dwBytesRecorded);
while (nLen >= AUDIO_BUFFER_SIZE) {
nRet = play_midi(nLen);
if (nRet == 1)
return PLUGIN_RET_EOF;
if (nRet == 2)
return PLUGIN_RET_SUCCESS;
nLen = GetSampleCount(pHdr->dwBufferLength - pHdr->dwBytesRecorded);
}
return PLUGIN_RET_SUCCESS;
}
void WINAPI midiStop()
{
stop_play_midi();
seek_midi(0);
}
void WINAPI midiClose()
{
close_midi();
memset(g_szCopyright, 0, sizeof(g_szCopyright));
memset(g_szTrack, 0, sizeof(g_szTrack));
}
BOOL WINAPI midiGetTag(MAP_PLUGIN_FILETAG* pTag)
{
if (!strlen(g_szCopyright) && !strlen(g_szTrack))
return FALSE;
pTag->nTrackNum = 0;
pTag->nYear = 0;
*pTag->szAlbum = NULL;
*pTag->szArtist = NULL;
*pTag->szGenre = NULL;
#ifdef _UNICODE
if (strlen(g_szCopyright))
MultiByteToWideChar(CP_ACP, 0, g_szCopyright, -1, pTag->szComment, MAX_PLUGIN_TAG_STR);
if (strlen(g_szTrack))
MultiByteToWideChar(CP_ACP, 0, g_szTrack, -1, pTag->szTrack, MAX_PLUGIN_TAG_STR);
#else
_tcscpy(pTag->szComment, g_szCopyright);
_tcscpy(pTag->szTrack, g_szTrack);
#endif
return TRUE;
}
BOOL WINAPI midiGetFileTag(LPCTSTR pszFile, MAP_PLUGIN_FILETAG* pTag)
{
char szTrack[256];
char szCopyright[256];
if (!ReadMidiText(pszFile, szCopyright, szTrack))
return FALSE;
if (!strlen(szCopyright) && !strlen(szTrack))
return FALSE;
pTag->nTrackNum = 0;
pTag->nYear = 0;
*pTag->szAlbum = NULL;
*pTag->szArtist = NULL;
*pTag->szGenre = NULL;
#ifdef _UNICODE
if (strlen(g_szCopyright))
MultiByteToWideChar(CP_ACP, 0, szCopyright, -1, pTag->szComment, MAX_PLUGIN_TAG_STR);
if (strlen(g_szTrack))
MultiByteToWideChar(CP_ACP, 0, szTrack, -1, pTag->szTrack, MAX_PLUGIN_TAG_STR);
#else
_tcscpy(pTag->szComment, szCopyright);
_tcscpy(pTag->szTrack, szTrack);
#endif
return TRUE;
}
BOOL WINAPI midiOpenStreaming(LPBYTE pbBuf, DWORD cbBuf, MAP_PLUGIN_STREMING_INFO* pInfo)
{
return FALSE;
}
int WINAPI midiDecodeStreaming(LPBYTE pbInBuf, DWORD cbInBuf, DWORD* pcbInUsed, WAVEHDR* pHdr)
{
return PLUGIN_RET_ERROR;
}
void WINAPI midiCloseStreaming()
{
}
MAP_DEC_PLUGIN* WINAPI mapGetDecoder()
{
plugin.dwVersion = PLUGIN_DEC_VER;
plugin.dwChar = sizeof(TCHAR);
plugin.Init = midiInit;
plugin.Quit = midiQuit;
plugin.GetFunc = midiGetFunc;
plugin.GetPluginName = midiGetPluginName;
plugin.GetFileExtCount = midiGetFileExtCount;
plugin.GetFileExt = midiGetFileExt;
plugin.SetEqualizer = midiSetEqualizer;
plugin.IsValidFile = midiIsValidFile;
plugin.ShowConfigDlg = midiShowConfigDlg;
plugin.OpenFile = midiOpen;
plugin.SeekFile = midiSeek;
plugin.StartDecodeFile = midiStart;
plugin.DecodeFile = midiDecode;
plugin.StopDecodeFile = midiStop;
plugin.CloseFile = midiClose;
plugin.OpenStreaming = midiOpenStreaming;
plugin.DecodeStreaming = midiDecodeStreaming;
plugin.CloseStreaming = midiCloseStreaming;
plugin.GetTag = midiGetTag;
plugin.GetFileTag = midiGetFileTag;
return &plugin;
}