⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w32_a.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    w32_a.c    Functions to play sound on the Windows audio driver (Windows 95/98/NT).    Modified by Masanao Izumo <mo@goice.co.jp>*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#ifdef __W32__#include "interface.h"#endif#include <stdio.h>#include <stdlib.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include <windows.h>extern CRITICAL_SECTION critSect;/*****************************************************************************************************************************/#if defined(__CYGWIN32__) || defined(__MINGW32__)#ifdef HAVE_NEW_MMSYSTEM#include <mmsystem.h>#else/* On cygnus, there is not mmsystem.h for Multimedia API's. * mmsystem.h can not distribute becase of Microsoft Lisence * Then declare some of them here. **/#define WOM_OPEN                0x3BB#define WOM_CLOSE               0x3BC#define WOM_DONE                0x3BD#define WAVE_FORMAT_QUERY       0x0001#define WAVE_ALLOWSYNC          0x0002#define WAVE_FORMAT_PCM         1#define CALLBACK_FUNCTION       0x00030000l#define WAVERR_BASE             32#define WAVE_MAPPER             (UINT)-1DECLARE_HANDLE(HWAVEOUT);DECLARE_HANDLE(HWAVE);typedef HWAVEOUT *LPHWAVEOUT;/* Define WAVEHDR, WAVEFORMAT structure */typedef struct wavehdr_tag{    LPSTR       lpData;    DWORD       dwBufferLength;    DWORD       dwBytesRecorded;    DWORD       dwUser;    DWORD       dwFlags;    DWORD       dwLoops;    struct wavehdr_tag *lpNext;    DWORD       reserved;} WAVEHDR;typedef struct{    WORD    wFormatTag;    WORD    nChannels;    DWORD   nSamplesPerSec;    DWORD   nAvgBytesPerSec;    WORD    nBlockAlign;    WORD    wBitsPerSample;    WORD    cbSize;} WAVEFORMAT, WAVEFORMATEX, *LPWAVEFORMATEX;typedef struct waveoutcaps_tag{    WORD    wMid;    WORD    wPid;    UINT    vDriverVersion;#define MAXPNAMELEN      32    char    szPname[MAXPNAMELEN];    DWORD   dwFormats;    WORD    wChannels;    DWORD   dwSupport;} WAVEOUTCAPS;typedef WAVEHDR *       LPWAVEHDR;typedef WAVEFORMAT *    LPWAVEFORMAT;typedef WAVEOUTCAPS *   LPWAVEOUTCAPS;typedef UINT            MMRESULT;MMRESULT WINAPI waveOutOpen(LPHWAVEOUT, UINT, LPWAVEFORMAT, DWORD, DWORD, DWORD);MMRESULT WINAPI waveOutClose(HWAVEOUT);MMRESULT WINAPI waveOutPrepareHeader(HWAVEOUT, LPWAVEHDR, UINT);MMRESULT WINAPI waveOutUnprepareHeader(HWAVEOUT, LPWAVEHDR, UINT);MMRESULT WINAPI waveOutWrite(HWAVEOUT, LPWAVEHDR, UINT);UINT     WINAPI waveOutGetNumDevs(void);MMRESULT WINAPI waveOutReset(HWAVEOUT);MMRESULT WINAPI waveOutGetDevCaps(UINT, LPWAVEOUTCAPS, UINT);MMRESULT WINAPI waveOutGetDevCapsA(UINT, LPWAVEOUTCAPS, UINT);#define waveOutGetDevCaps waveOutGetDevCapsAMMRESULT WINAPI waveOutGetID(HWAVEOUT, UINT*);#endif#endif /* __CYGWIN32__ *//*****************************************************************************************************************************/#include "timidity.h"#include "output.h"#include "controls.h"#include "timer.h"#include "instrum.h"#include "playmidi.h"#include "mblock.h"#include "miditrace.h"#include "interface.h"#define NOT !static int  open_output     (void); /* 0=success, 1=warning, -1=fatal error */static void close_output    (void);static int  output_data     (char * Data, int32 Size);static int  acntl           (int request, void * arg);#if defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )//#if defined ( IA_W32GUI )volatile int data_block_bits = DEFAULT_AUDIO_BUFFER_BITS;volatile int data_block_num = 64;#endif#define DATA_BLOCK_SIZE     (4 * AUDIO_BUFFER_SIZE)#define DATA_BLOCK_NUM      (dpm.extra_param[0])struct MMBuffer{    int                 Number;    int                 Prepared;   // Non-zero if this buffer has been prepared.    HGLOBAL             hData;    void *              Data;    HGLOBAL             hHead;    WAVEHDR *           Head;    struct MMBuffer *   Next;};static struct MMBuffer *            Buffers;static volatile struct MMBuffer *   FreeBuffers;static volatile int                 NumBuffersInUse;static HWAVEOUT                     hDevice;static int                          BufferDelay;                    // in millisecondsstatic const int                    AllowSynchronousWaveforms = 1;/*****************************************************************************************************************************/static void CALLBACK                OnPlaybackEvent (HWAVE hWave, UINT Msg, DWORD UserData, DWORD Param1, DWORD Param2);static void                         BufferPoolReset (void);static struct MMBuffer *            GetBuffer       ();static void                         PutBuffer       (struct MMBuffer *);static const char *                 MMErrorMessage  (MMRESULT Result);static void                         WaitForBuffer   (int WaitForAllBuffers);/*****************************************************************************************************************************/static int detect(void);#define dpm w32_play_modePlayMode dpm ={    DEFAULT_RATE,    PE_16BIT | PE_SIGNED,    PF_PCM_STREAM|PF_CAN_TRACE|PF_BUFF_FRAGM_OPT,    -1,    {32},    "Windows audio driver", 'd',    NULL,    open_output,    close_output,    output_data,    acntl,	detect};/*****************************************************************************************************************************/static int open_output(void){    int             i;    int             j;    int             IsMono;    WAVEFORMATEX    wf;    WAVEOUTCAPS     woc;    MMRESULT        Result;    UINT            DeviceID;    if (dpm.extra_param[0] < 8)    {        ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Too small -B option: %d", dpm.extra_param[0]);        dpm.extra_param[0] = 8;    }/** Check if there is at least one audio device. **/    if (waveOutGetNumDevs() == 0)    {        ctl->cmsg (CMSG_ERROR, VERB_NORMAL, "No audio devices present!");        return -1;    }/** They can't mean these. **/    dpm.encoding &= ~(PE_ULAW | PE_ALAW | PE_BYTESWAP);    if (dpm.encoding & PE_16BIT || dpm.encoding & PE_24BIT)        dpm.encoding |= PE_SIGNED;    else        dpm.encoding &= ~PE_SIGNED;    IsMono  = (dpm.encoding & PE_MONO);    memset(&wf, 0, sizeof(wf));    wf.wFormatTag     = WAVE_FORMAT_PCM;    wf.nChannels      = IsMono ? 1 : 2;    wf.nSamplesPerSec = dpm.rate;    i = dpm.rate;    j = 1;    if (!IsMono)    {        i *= 2;        j *= 2;    }	if (dpm.encoding & PE_24BIT) {		i *= 3;		j *= 3;	} else if (dpm.encoding & PE_16BIT) {        i *= 2;        j *= 2;    }    wf.nAvgBytesPerSec = i;    wf.nBlockAlign     = j;	if (dpm.encoding & PE_24BIT) {		wf.wBitsPerSample  = 24;	} else if (dpm.encoding & PE_16BIT) {		wf.wBitsPerSample  = 16;	} else {		wf.wBitsPerSample  = 8;	}    wf.cbSize          = sizeof(WAVEFORMAT);/** Open the device. **/    { CHAR  b[256]; wsprintf(b, "Opening device...\n"); OutputDebugString(b); }    hDevice = 0;    if (AllowSynchronousWaveforms)        Result = waveOutOpen(&hDevice, WAVE_MAPPER, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION | WAVE_ALLOWSYNC);    else        Result = waveOutOpen(&hDevice, WAVE_MAPPER, (LPWAVEFORMATEX) &wf, (DWORD) OnPlaybackEvent, 0, CALLBACK_FUNCTION);    if (Result)    {        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't open audio device: " "encoding=<%s>, rate=<%d>, ch=<%d>: %s", output_encoding_string(dpm.encoding), dpm.rate, wf.nChannels, MMErrorMessage(Result));        return -1;    }    else        { CHAR  b[256]; wsprintf(b, "Device opened.\n"); OutputDebugString(b); }/** Get the device ID. **/    DeviceID = 0;    waveOutGetID(hDevice, &DeviceID);/** Get the device capabilities. **/    memset(&woc, 0, sizeof(WAVEOUTCAPS));    Result = waveOutGetDevCaps(DeviceID, &woc, sizeof(WAVEOUTCAPS));    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Device ID: %d",              DeviceID);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Manufacture ID: %d",         woc.wMid);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Product ID: %d",             woc.wPid);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Driver version: %d",         woc.vDriverVersion);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Product name: %s",           woc.szPname);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Formats supported: 0x%08X",  woc.dwFormats);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Max. channels: %d",          woc.wChannels);    ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Supported features: 0x%08X", woc.dwSupport);/** Calculate the buffer delay. **/    BufferDelay = AUDIO_BUFFER_SIZE;    if (NOT (dpm.encoding & PE_MONO))        BufferDelay *= 2;	if (dpm.encoding & PE_24BIT)		BufferDelay *= 3;    else if (dpm.encoding & PE_16BIT)        BufferDelay *= 2;    BufferDelay = (BufferDelay * 1000) / dpm.rate;/** Create the buffer pool. **/    Buffers = (struct MMBuffer *) safe_malloc(DATA_BLOCK_NUM * sizeof(struct MMBuffer));    for (i = 0; i < DATA_BLOCK_NUM; i++)    {        struct MMBuffer *   b;        b = &Buffers[i];        b->hData = GlobalAlloc(GMEM_ZEROINIT, DATA_BLOCK_SIZE);        b->Data  = GlobalLock (b->hData);        b->hHead = GlobalAlloc(GMEM_ZEROINIT, sizeof(WAVEHDR));        b->Head  = GlobalLock (b->hHead);    }    BufferPoolReset();/** Set the file descriptor. **/    dpm.fd = 0;    return 0;}/*****************************************************************************************************************************/static void close_output(void){    int i;    if (dpm.fd != -1)    {        WaitForBuffer(1);        { CHAR  b[256]; wsprintf(b, "Closing device...\n"); OutputDebugString(b); }        waveOutReset(hDevice);        waveOutClose(hDevice);        { CHAR  b[256]; wsprintf(b, "Device closed.\n"); OutputDebugString(b); }    /** Free all buffers. **/        for (i = 0; i < DATA_BLOCK_NUM; i++)        {            struct MMBuffer *   block;            block = &Buffers[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -