/*------------------------------------------------------------------------------------*/ /*声音设备函数 */ /*------------------------------------------------------------------------------------*/ //本程序库带32声道混音 /*---------------------------------------------------------------------*/ UINT AIAPI AInitialize(void) //初始化,DOS下必须 /*---------------------------------------------------------------------*/ UINT AIAPI AGetAudioDevCaps(UINT nDeviceId, LPAUDIOCAPS lpCaps) //得到声音设备的信息(成功返回0) nDeviceId 声音设备识别号 lpCaps 一个AUDIOCAPS结构的地址指针 /////////////////////////////////////////// VOID PrintAudioDevs(VOID) { AUDIOCAPS caps; UINT nDeviceId;
/* show all the installed device drivers */ for (nDeviceId = 0; nDeviceId < AGetAudioNumDevs(); nDeviceId++) { AGetAudioDevCaps(nDeviceId, &caps); printf(nDeviceId=%d wProductId=%d szProductName=%s\n? nDeviceId, caps.wProductId, caps.szProductName); } }
/*---------------------------------------------------------------------*/ AUDIOCAPS结构 //说明声音设备的能力 typedef struct { WORD wProductId; CHAR szProductName[30]; DWORD dwFormats; } AUDIOCAPS, *LPAUDIOCAPS; /////////////////////////////////////////// wProductId //硬件标识,具有以下值
Value Description AUDIO_PRODUCT_NONE Virtual silence device AUDIO_PRODUCT_SB Sound Blaster 1.0 device AUDIO_PRODUCT_SB15 Sound Blaster 1.5 device AUDIO_PRODUCT_SB20 Sound Blaster 2.0 device AUDIO_PRODUCT_SBPRO Sound Blaster Pro I or II device AUDIO_PRODUCT_SB16 Sound Blaster 16/ASP device AUDIO_PRODUCT_AWE32 Sound Blaster AWE32 device AUDIO_PRODUCT_WSS Windows Sound System device
AUDIO_PRODUCT_ESS Ensoniq Soundscape (Elite) device AUDIO_PRODUCT_GUS Gravis Ultrasound (GF1) device AUDIO_PRODUCT_GUSDB Gravis Ultrasound Daughterboard device AUDIO_PRODUCT_GUSMAX Gravis Ultrasound Max (CS4231) device AUDIO_PRODUCT_IWAVE AMD Interwave-based device AUDIO_PRODUCT_PAS Pro Audio Spectrum (Plus) device AUDIO_PRODUCT_PAS16 Pro Audio Spectrum 16 device
AUDIO_PRODUCT_ARIA Sierra Semiconductors Aria Sound device AUDIO_PRODUCT_WINDOWS Microsoft Windows WAVE device AUDIO_PRODUCT_DSOUND Microsoft Windows DirectSound device AUDIO_PRODUCT_LINUX UNIX Sound System for Linux device AUDIO_PRODUCT_SPARC SPARC workstation 8-bit ulaw or dbri device AUDIO_PRODUCT_SGI Silicon Graphics Indigo Audio Ports device /////////////////////////////////////////// szProductName 硬件产品名称字符串,NULL结束 /////////////////////////////////////////// dwFormats 产品回放能力标示
Value Description AUDIO_FORMAT_1M08 8-bit mono 11025 Hz AUDIO_FORMAT_1S08 8-bit stereo 11025 Hz AUDIO_FORMAT_1M16 16-bit mono 11025 Hz AUDIO_FORMAT_1S16 16-bit stereo 11025 Hz AUDIO_FORMAT_2M08 8-bit mono 22050 Hz AUDIO_FORMAT_2S08 8-bit stereo 22050 Hz AUDIO_FORMAT_2M16 16-bit mono 22050 Hz AUDIO_FORMAT_2S16 16-bit stereo 22050 Hz AUDIO_FORMAT_4M08 8-bit mono 44100 Hz AUDIO_FORMAT_4S08 8-bit stereo 44100 Hz
AUDIO_FORMAT_4M16 16-bit mono 44100 Hz AUDIO_FORMAT_4S16 16-bit stereo 44100 Hz /*---------------------------------------------------------------------*/ UINT AIAPI AGetAudioNumDevs(VOID) //返回安装的声音设备个数 /*---------------------------------------------------------------------*/ UINT AIAPI APingAudio(LPUINT lpnDeviceId) //自动发现声音设备 lpnDeviceId 无符号整数指针,指向ID /////////////////////////////////////////// VOID DetectAudioDevice(VOID) { AUDIOCAPS caps; UINT nDeviceId; if (APingAudio(&nDeviceId)?= AUDIO_ERROR_NONE) { printf(搉o audio device found.\n?; } else { AGetAudioDevCaps(nDeviceId, &caps); printf(?s device found.\n? caps.szProductName); } } /*---------------------------------------------------------------------*/ UINT AIAPI AOpenAudio(LPAUDIOINFO lpInfo) //打开声音设备,成功返回0 lpInfo AUDIOINFO结构指针,设定回放参数 /////////////////////////////////////////// VOID InitializeAudio(VOID) { AUDIOINFO info; info.nDeviceId = AUDIO_DEVICE_MAPPER; info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO; info.nSampleRate = 44100; if (AOpenAudio(&info)?= AUDIO_ERROR_NONE) { printf("Audio initialization failed.\n"); exit(1); } else { printf("Audio device initialized at %d bits %s %u Hz\n", info.wFormat & AUDIO_FORMAT_16BITS?"16:8", info.wFormat & AUDIO_FORMAT_STEREO?"stereo:mono",info.nSampleRate); } } /*---------------------------------------------------------------------*/ typedef struct //声音回放设定 { UINT nDeviceId; WORD wFormat; WORD nSampleRate; } AUDIOINFO, *LPAUDIOINFO; /////////////////////////////////////////// nDeviceId //指定我们希望回放的设备 Value Description AUDIO_DEVICE_NONE Silence device driver AUDIO_DEVICE_MAPPER Audio mapper driver /////////////////////////////////////////// wFormat //回放格式 Value Description AUDIO_FORMAT_8BITS 8 bits per sample AUDIO_FORMAT_16BITS 16 bits per sample AUDIO_FORMAT_MONO Monophonic output AUDIO_FORMAT_STEREO Stereo output AUDIO_FORMAT_FILTER Enable filtering /////////////////////////////////////////// nSampleRate //回放频率,推荐使用11025,22050,44100Hz /*---------------------------------------------------------------------*/ UINT AIAPI AUpdateAudio(VOID) //向声音设备送声音值(返0成功),DOS下必须 //必须周期性的调用(至少每秒钟调用一次) /*---------------------------------------------------------------------*/ UINT AIAPI ACloseAudio(VOID) //关闭声音设备(返0成功) /*---------------------------------------------------------------------*/ //////////////////////////时钟中断服务/////////////////////////////////// /*---------------------------------------------------------------------*/ UINT AIAPI ASetAudioTimerProc(LPFNAUDIOTIMER lpfnAudioTimer) //安装时钟服务程序(返0成功),后台回放,用户程序不可再用 lpfnAudioTimer 时钟处理程序地址 /////////////////////////////////////////// volatile UINT nTickCounter = 0;
VOID AIAPI TimerHandler(VOID) { nTickCounter++; }
VOID InitTimerHandler(VOID) { /* the handler will be called at 125 BPM (50 times per second) */ ASetAudioTimerProc(TimerHandler); ASetAudioTimerRate(125); }
VOID DoneTimerHandler(VOID) { ASetAudioTimerProc(NULL); } /*---------------------------------------------------------------------*/ UINT AIAPI ASetAudioTimerRate(UINT nTimerRate) //改变时钟频率(返0成功) nTimerRate 每分钟拍节(32-255) /*---------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/ /*Voice函数 */ /*------------------------------------------------------------------------------------*/ UINT AIAPI AOpenVoices(UINT nVoices) //打开声音设备(0成功) nVoices 最大声道数(1-32)(可能是混音声道数) /*---------------------------------------------------------------------*/ UINT AIAPI ACreateAudioVoice(LPHAC lphVoice) //分配1条声道(0成功) lphVoice 声道头 /////////////////////////////////////////// VOID PlayWaveform(LPAUDIOWAVE lpWave) { HAC hVoice; BOOL stopped;
/* allocate an audio voice or channel */ if (ACreateAudioVoice(&hVoice)?= AUDIO_ERROR_NONE) {
/* play the waveform through the voice */ APlayVoice(hVoice, lpWave); ASetVoiceVolume(hVoice, 64); ASetVoicePanning(hVoice, 128);
/* wait until the wave finishes or a key is pressed */ while (!kbhit()) { AUpdateAudio(); AGetVoiceStatus(hVoice, &stopped); if (stopped) break; }
/* stop the voice (if already playing) */ AStopVoice(hVoice);
/* release the allocated voice */ ADestroyAudioVoice(hVoice); } } /*---------------------------------------------------------------------*/ UINT AIAPI ADestroyAudioVoice(HAC hVoice) //释放一个声道(每条声音播完后必须释放) hVoice 声道头 /*---------------------------------------------------------------------*/ UINT AIAPI ACloseVoices(VOID) //关闭所有声音 /*---------------------------------------------------------------------*/ UINT AIAPI APlayVoice(HAC hVoice, LPAUDIOWAVE lpWave) //开始播放一条波形 hVoice 声道头 lpWave wave结构指针 /*---------------------------------------------------------------------*/ UINT AIAPI APrimeVoice(HAC hVoice, LPAUDIOWAVE lpWave) //准备一条wave到声道上 hVoice 声道头 lpWave wave结构指针 /////////////////////////////////////////// VOID PlayChord(HAC aVoices[3], LPAUDIOWAVE lpWave, LONG aFreqs[3]) { UINT n;
/* first prepare the voices to play the waveform */ for (n = 0? n < 3? n++) { APrimeVoice(aVoices[n], lpWave); ASetVoiceFrequency(aVoices[n], aFreqs[n]); ASetVoiceVolume(aVoices[n], 64); }
/* now start playing all them simultaneously */ for (n = 0? n < 3? n++) { AStartVoice(aVoices[n]); } } /*---------------------------------------------------------------------*/ UINT AIAPI AStartVoice(HAC hVoice) //播放一个声道,可以指定连续循环播放 hVoice 声道头 /*---------------------------------------------------------------------*/ UINT AIAPI AStopVoice(HAC hVoice) //停止播放一个声道 hVoice 声道头 /*---------------------------------------------------------------------*/ UINT AIAPI AGetVoicePosition(HAC hVoice, LPLONG lpdwPosition) //返回正在播放的声音位置(播放点,做拉条用) hVoice //询问的声道头 lpdwPosition //长指针返回播放点 /*---------------------------------------------------------------------*/ UINT AIAPI ASetVoicePosition(HAC hVoice, LONG dwPosition) //设定正在播放的声音位置(播放点,做拉条用) hVoice //设定的声道头 lpdwPosition //长指针设定播放点 /////////////////////////////////////////// VOID PlayEchoVoices(HAC aVoices[2], LPAUDIOWAVE lpWave, LONG dwDelay) { /* prepare two voices with the same waveform */ APrimeVoice(aVoices[0], lpWave); APrimeVoice(aVoices[1], lpWave); ASetVoiceFrequency(aVoices[0], lpWave->nSampleRate); ASetVoiceFrequency(aVoices[1], lpWave->nSampleRate);
/* set voice volumes (the 揺cho?voice has a lower volume) */ ASetVoiceVolume(aVoices[0], 64); ASetVoiceVolume(aVoices[1], 32);
/* set the delay (measured in samples) for the 揺cho?voice */ ASetVoicePosition(aVoices[1], dwDelay);
/* start both voices as simultenously as possible */ AStartVoice(aVoices[0]); AStartVoice(aVoices[1]); } /*---------------------------------------------------------------------*/ UINT AIAPI AGetVoiceVolume(HAC hVoice, LPUINT lpnVolume) //得到声道的音量 hVoice //询问的声道头 lpdwPosition //无符号整形指针返回音量 /*---------------------------------------------------------------------*/ UINT AIAPI ASetVoiceVolume(HAC hVoice, UINT nVolume) //设定声道的音量 hVoice //设定的声道头 lpdwPosition //无符号整形指针设定音量 /*---------------------------------------------------------------------*/ UINT AIAPI AGetVoiceFrequency(HAC hVoice, LPLONG lpdwFrequency) //返回声道取样频率 lpdwFrequency 每秒Hz数 /*---------------------------------------------------------------------*/ UINT AIAPI ASetVoiceFrequency(HAC hVoice, LONG dwFrequency) //设定声道取样频率 dwFrequency 每秒Hz数 /////////////////////////////////////////// VOID PlayVoiceStereo(HAC aVoices[2], LPAUDIOWAVE lpWave, LONG dwPitchShift) { /* prepare two voices to play a waveform */ APrimeVoice(aVoices[0], lpWave); APrimeVoice(aVoices[1], lpWave); ASetVoiceVolume(aVoices[0], 64); ASetVoiceVolume(aVoices[1], 64);
/* slightly change the pitch of one of the voices */ ASetVoiceFrequency(aVoices[0], lpWave->nSampleRate); ASetVoiceFrequency(aVoices[1], lpWave->nSampleRate + dwPitchShift);
/* set the pan position of the voices to left and right */ ASetVoicePanning(aVoices[0], 0); ASetVoicePanning(aVoices[1], 255);
/* start both voices simultaneously */ AStartVoice(aVoices[0]); AStartVoice(aVoices[1]); } /*---------------------------------------------------------------------*/ UINT AIAPI AGetVoicePanning(HAC hVoice, LPUINT lpnPanning) //返回立体声面板(?)位置 lpnPanning unsigned integer指针 /*---------------------------------------------------------------------*/ UINT AIAPI ASetVoicePanning(HAC hVoice, UINT nPanning) //改变立体声面板(?)位置 nPanning 立体声面板值(0-255) /*---------------------------------------------------------------------*/ UINT AIAPI AGetVoiceStatus(HAC hVoice, LPBOOL lpbStatus) //返回当前声音状态 /////////////////////////////////////////// lpbStatus boolean变量指针 VOID CheckVoice(HAC hVoice) { BOOL stopped; AGetVoiceStatus(hVoice, &stopped); if (stopped) printf("voice is stopped.\n"); } /*-----------------------------------------------------------------------*/ /*Wave函数 */ /*-----------------------------------------------------------------------*/ UINT AIAPI ALoadWaveFile(LPSTR lpszFileName, LPAUDIOWAVE* lplpWave,DWORD dwOffset) //LOAD一个RIFF/WAVE文件 lpszFileName Filename of the .WAV waveform file on disk. lplpWave Address of a pointer to a waveform structure. dwOffset Starting file offset of the waveform file. /////////////////////////////////////////// VOID PlayWaveFile(HAC hVoice, LPSTR lpszFileName) { LPAUDIOWAVE lpWave; BOOL stopped;
if (ALoadWaveFile(lpszFileName, &lpWave, 0L)?= AUDIO_ERROR_NONE) { APlayVoice(hVoice, lpWave); ASetVoiceVolume(hVoice, 64); while (!kbhit()) { AUpdateAudio(); AGetVoiceStatus(hVoice, &stopped); if (stopped) break; } AFreeWaveFile(lpWave); } } /*---------------------------------------------------------------------*/ UINT AIAPI AFreeWaveFile(LPAUDIOWAVE lpWave) //释放一个WAV文件 /*---------------------------------------------------------------------*/ UINT AIAPI ACreateAudioData(LPAUDIOWAVE lpWave) //建立一个WAV对象 lpWave 指向WAVE结构的指针 /////////////////////////////////////////// LPAUDIOWAVE CreateAudio8BitMono(WORD nSampleRate,LPBYTE lpData, DWORD dwLength) { LPAUDIOWAVE lpWave; /* first allocate structure to hold the waveform object */ if ((lpWave = (LPAUDIOWAVE) malloc(sizeof(AUDIOWAVE)))?= NULL) { /* create a 8-bit mono one-shot waveform object */ lpWave->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO; lpWave->nSampleRate = nSampleRate; lpWave->dwLength = dwLength; lpWave->dwLoopStart = lpWave->dwLoopEnd = 0; if (ACreateAudioData(lpWave)?= AUDIO_ERROR_NONE) { free(lpWave); return NULL; } /* copy the data into the waveform object */ memcpy(lpWave->lpData, lpData, dwLength); /* upload the data to the audio DRAM local memory */ AWriteAudioData(lpWave, 0L, dwLength); } return lpWave; } /*---------------------------------------------------------------------*/ UINT AIAPI ADestroyAudioData(LPAUDIOWAVE lpWave) //释放一个WAVE对象 /*---------------------------------------------------------------------*/ typedef struct WAVE结构 { LPBYTE lpData; DWORD dwHandle; DWORD dwLength; DWORD dwLoopStart; DWORD dwLoopEnd; WORD nSampleRate; WORD wFormat; } AUDIOWAVE, *LPAUDIOWAVE; /////////////////////////////////////////// lpData 只读,数据地址指针 /////////////////////////////////////////// dwHandle 只读,声音设备使用的句柄 /////////////////////////////////////////// dwLength 指定字节为单位的波形数据长度 /////////////////////////////////////////// dwLoopStart 循环模式下的循环起始点 /////////////////////////////////////////// dwLoopEnd 循环模式下的循环结束点 /////////////////////////////////////////// nSampleEate 波形数据约定的取样频率 /////////////////////////////////////////// wFormat 波形数据格式 Value Description AUDIO_FORMAT_8BITS 8 bits per sample AUDIO_FORMAT_16BITS 16 bits per sample AUDIO_FORMAT_MONO Monophonic output AUDIO_FORMAT_STEREO Stereo output AUDIO_FORMAT_LOOP Forward looping 向前循环 AUDIO_FORMAT_BIDILOOP Bidirectional looping 双向循环 AUDIO_FORMAT_REVERSE Reverse playing 反向播放 /*------------------------------------------------------------------------------------*/ /*Music函数 */ /*------------------------------------------------------------------------------------*/ UINT AIAPI ALoadModuleFile(LPSTR lpszFileName, LPAUDIOMODULE* lplpModule,DWORD dwOffset) //调入一个MOD/MTM/S3M/XM文件 /*---------------------------------------------------------------------*/ UINT AIAPI AFreeModuleFile(LPAUDIOMODULE lpModule) //释放一个MOD/MTM/S3M/XM文件 /*---------------------------------------------------------------------*/ UINT AIAPI APlayModule(LPAUDIOMODULE lpModule) //播放一个音乐文件 /*---------------------------------------------------------------------*/ UINT AIAPI AStopModule(VOID) //停止播放音乐文件 /*---------------------------------------------------------------------*/ UINT AIAPI APauseModule(VOID) //暂停播放音乐文件 /*---------------------------------------------------------------------*/ UINT AIAPI AResumeModule(VOID) //重新开始继续播放音乐文件 /*---------------------------------------------------------------------*/ UINT AIAPI AGetModulePosition(LPUINT lpnOrder, LPUINT lpnRow) //返回声音文件播放位置 /*---------------------------------------------------------------------*/ UINT AIAPI ASetModulePosition(UINT nOrder, UINT nRow) //改变声音文件播放位置 /*---------------------------------------------------------------------*/ UINT AIAPI AGetModuleVolume(LPUINT lpnVolume) //返回声音文件播放音量 /*---------------------------------------------------------------------*/ UINT AIAPI ASetModuleVolume(LPUINT lpnVolume) //改变声音文件播放音量(0-64) /*---------------------------------------------------------------------*/ typedef struct //音乐结构 { CHAR szModuleName[32]; WORD wFlags; WORD nOrders; WORD nRestart; WORD nTracks; WORD nPatterns; WORD nPatches; WORD nTempo; WORD nBPM; BYTE aOrderTable[AUDIO_MAX_ORDERS]; BYTE aPanningTable[AUDIO_MAX_VOICES]; LPAUDIOPATTERN aPatternTable; LPAUDIOPATCH aPatchTable; } AUDIOMODULE, *LPAUDIOMODULE; /////////////////////////////////////////// szModuleName 音乐模块名,字符串(32字节) /////////////////////////////////////////// wFlags 音乐格式 Value Description AUDIO_MODULE_LINEAR The module uses linear frequencies 线性格式 AUDIO_MODULE_AMIGA Use Amiga logarithmic frequencies 对数格式 AUDIO_MODULE_PANNING Use pan position from instruments 方位格式 /////////////////////////////////////////// nOrders 次序表个数 /////////////////////////////////////////// nRestart 重复时的起点 /////////////////////////////////////////// nTracks 音乐声道数 /////////////////////////////////////////// nPatterns 音乐模型数 /////////////////////////////////////////// nPatches 修补工具数 /////////////////////////////////////////// nTempo 节拍速度 /////////////////////////////////////////// nBPM 每分钟节拍数 /////////////////////////////////////////// aOrderTable 模型播放次序(因为本程序包采用波形模拟方式,模型指波形) /////////////////////////////////////////// aPanningTable 立体声位置 /////////////////////////////////////////// aPatternTable 模型结构 /////////////////////////////////////////// aPatchTable 修补片结构 /*---------------------------------------------------------------------*/ 返回码 Value Description AUDIO_ERROR_NONE No error ==0 AUDIO_ERROR_INVALHANDLE Invalid voice or waveform handle AUDIO_ERROR_INVALPARAM Invalid parameter passed AUDIO_ERROR_NOTSUPPORTED Invalid audio system call AUDIO_ERROR_BADDEVICEID Invalid device identifier AUDIO_ERROR_NODEVICE No audio device found AUDIO_ERROR_DEVICEBUSY Audio device is busy AUDIO_ERROR_BADFORMAT Bad or unsupported audio playback format
AUDIO_ERROR_NOMEMORY Not enough system memory AUDIO_ERROR_NODRAMMEMORY Not enough onboard DRAM memory AUDIO_ERROR_FILENOTFOUND Module or waveform file not found AUDIO_ERROR_BADFILEFORMAT Invalid module or waveform file format /*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/ 系统分析(肖舸): 1 系统音乐由MOD,S3M格式播放,声音播放WAV文件 2 音乐可以一次装入多个,按道管理,像CD一样,声音可以一次装入多个,通过声道播放,32个 声道可以混音,同时,声道还标示立体声播放时的方位 3 系统内建后台播放,采用时钟中断,但可能与我们的时钟冲突,不建议使用,而应该在我们 的时钟中使用AUpdateAudio函数播放 4 系统内建声音/音乐文件管理,可以使用 /*---------------------------------------------------------------------*/
|