📄 wince_audio.c
字号:
/* PocketCultMAME - MAME Emulator for PocketPC
(c) Copyright 2006 Manuel Castrillo Mart韓ez
Some parts of this file was licensed under MAME License terms.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "wince_util.h"
#include "wince_audio.h"
#include "driver.h"
#include "audio.h"
#include "wince_cfg.h"
extern cfgStruct GameConfig;
/* audio related stuff */
#define NUMVOICES 16
HAC hVoice[NUMVOICES];
LPAUDIOWAVE lpWave[NUMVOICES];
unsigned char No_FM = 1;
unsigned char No_OPL = 1;
unsigned char RegistersYM[264*5]; /* MAX 5 YM-2203 */
int nominal_sample_rate;
int soundcard,usefm,usestereo;
AUDIOINFO info;
AUDIOCAPS caps;
void osd_set_mastervolume(int nattenuation);
int msdos_init_seal (void)
{
if (AInitialize() == AUDIO_ERROR_NONE)
return 0;
else
return 1;
}
int msdos_init_sound(void)
{
int i;
No_OPL = No_FM = !usefm;
if( msdos_init_seal() != AUDIO_ERROR_NONE ) return 1;
/* initialize SEAL audio library */
if (soundcard == 0) /* silence */
{
/* update the Machine structure to show that sound is disabled */
Machine->sample_rate = 0;
return 0;
}
/* open audio device */
info.nDeviceId = AUDIO_DEVICE_MAPPER;
info.wFormat = GameConfig.sndBits | GameConfig.sndStereo;
info.nSampleRate = Machine->sample_rate;
if (AOpenAudio(&info) != AUDIO_ERROR_NONE)
{
writeLog("audio initialization failed\n");
return 1;
}
AGetAudioDevCaps(info.nDeviceId,&caps);
/* open and allocate voices, allocate waveforms */
if (AOpenVoices(NUMVOICES) != AUDIO_ERROR_NONE)
{
writeLog("voices initialization failed\n");
return 1;
}
for (i = 0; i < NUMVOICES; i++)
{
if (ACreateAudioVoice(&hVoice[i]) != AUDIO_ERROR_NONE)
{
return 1;
}
ASetVoicePanning(hVoice[i],128);
lpWave[i] = 0;
}
/* update the Machine structure to reflect the actual sample rate */
Machine->sample_rate = info.nSampleRate;
nominal_sample_rate = Machine->sample_rate;
return 0;
}
void msdos_shutdown_sound(void)
{
if (Machine->sample_rate != 0)
{
int n;
/* stop and release voices */
for (n = 0; n < NUMVOICES; n++)
{
AStopVoice(hVoice[n]);
ADestroyAudioVoice(hVoice[n]);
if (lpWave[n])
{
ADestroyAudioData(lpWave[n]);
free(lpWave[n]);
lpWave[n] = 0;
}
}
ACloseVoices();
ACloseAudio();
}
}
void osd_update_audio(void)
{
if (Machine->sample_rate == 0) return;
AUpdateAudioEx(Machine->sample_rate / Machine->drv->frames_per_second);
}
static void playsample(int channel,signed char *data,int len,int freq,int volume,int loop,int bits)
{
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return;
/* backwards compatibility with old 0-255 volume range */
if (volume > 100) volume = volume * 25 / 255;
if (lpWave[channel] && lpWave[channel]->dwLength != len)
{
AStopVoice(hVoice[channel]);
ADestroyAudioData(lpWave[channel]);
free(lpWave[channel]);
lpWave[channel] = 0;
}
if (lpWave[channel] == 0)
{
if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
return;
if (loop) lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
else lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO;
lpWave[channel]->nSampleRate = nominal_sample_rate;
lpWave[channel]->dwLength = len;
lpWave[channel]->dwLoopStart = 0;
lpWave[channel]->dwLoopEnd = len;
if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE)
{
free(lpWave[channel]);
lpWave[channel] = 0;
return;
}
}
else
{
if (loop) lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
else lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO;
}
memcpy(lpWave[channel]->lpData,data,len);
/* upload the data to the audio DRAM local memory */
AWriteAudioData(lpWave[channel],0,len);
APrimeVoice(hVoice[channel],lpWave[channel]);
/* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */
ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/Machine->sample_rate);
ASetVoiceVolume(hVoice[channel],volume * 64 / 100);
AStartVoice(hVoice[channel]);
}
void osd_play_sample(int channel,signed char *data,int len,int freq,int volume,int loop)
{
playsample(channel,data,len,freq,volume,loop,8);
}
void osd_play_sample_16(int channel,signed short *data,int len,int freq,int volume,int loop)
{
playsample(channel,(signed char *)data,len,freq,volume,loop,16);
}
static void playstreamedsample(int channel,signed char *data,int len,int freq,int volume,int pan,int bits)
{
static int playing[NUMVOICES];
static int c[NUMVOICES];
/* backwards compatibility with old 0-255 volume range */
if (volume > 100) volume = volume * 25 / 255;
if (pan != OSD_PAN_CENTER) volume /= 2;
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return;
if (!playing[channel])
{
if (lpWave[channel])
{
AStopVoice(hVoice[channel]);
ADestroyAudioData(lpWave[channel]);
free(lpWave[channel]);
lpWave[channel] = 0;
}
if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
return;
lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
| AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
lpWave[channel]->nSampleRate = nominal_sample_rate;
lpWave[channel]->dwLength = 3*len;
lpWave[channel]->dwLoopStart = 0;
lpWave[channel]->dwLoopEnd = 3*len;
if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE)
{
free(lpWave[channel]);
lpWave[channel] = 0;
return;
}
memset(lpWave[channel]->lpData,0,3*len);
memcpy(lpWave[channel]->lpData,data,len);
/* upload the data to the audio DRAM local memory */
AWriteAudioData(lpWave[channel],0,3*len);
APrimeVoice(hVoice[channel],lpWave[channel]);
/* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */
ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/Machine->sample_rate);
AStartVoice(hVoice[channel]);
playing[channel] = 1;
c[channel] = 1;
}
else
{
memcpy(&lpWave[channel]->lpData[len * c[channel]],data,len);
AWriteAudioData(lpWave[channel],len*c[channel],len);
c[channel]++;
if (c[channel] == 3) c[channel] = 0;
}
ASetVoiceVolume(hVoice[channel],volume * 64 / 100);
//if (pan == OSD_PAN_CENTER)
ASetVoicePanning(hVoice[channel],128);
//else if (pan == OSD_PAN_LEFT)
// ASetVoicePanning(hVoice[channel],0);
//else if (pan == OSD_PAN_RIGHT)
// ASetVoicePanning(hVoice[channel],255);
}
void osd_play_streamed_sample(int channel,signed char *data,int len,int freq,int volume,int pan)
{
playstreamedsample(channel,data,len,freq,volume,pan,8);
}
void osd_play_streamed_sample_16(int channel,signed short *data,int len,int freq,int volume,int pan)
{
playstreamedsample(channel,(signed char *)data,len,freq,volume,pan,16);
}
void osd_adjust_sample(int channel,int freq,int volume)
{
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return;
/* backwards compatibility with old 0-255 volume range */
if (volume > 100) volume = volume * 25 / 255;
/* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */
if (freq != -1)
ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/Machine->sample_rate);
if (volume != -1)
ASetVoiceVolume(hVoice[channel],volume * 64 / 100);
}
void osd_stop_sample(int channel)
{
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return;
AStopVoice(hVoice[channel]);
}
void osd_restart_sample(int channel)
{
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return;
AStartVoice(hVoice[channel]);
}
int osd_get_sample_status(int channel)
{
int stopped=0;
if (Machine->sample_rate == 0 || channel >= NUMVOICES) return -1;
AGetVoiceStatus(hVoice[channel], &stopped);
return stopped;
}
int attenuation = 0;
int master_volume = 256;
/* attenuation in dB */
void osd_set_mastervolume(int nattenuation)
{
float volume;
attenuation = nattenuation;
volume = 256.0; /* range is 0-256 */
while (nattenuation++ < 0)
volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */
master_volume = volume;
ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
}
int osd_get_mastervolume(void)
{
return attenuation;
}
void osd_sound_enable(int enable_it)
{
static int orig_attenuation;
if (enable_it)
{
ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
}
else
{
ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -