kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
184 wiersze
3.9 KiB
C
184 wiersze
3.9 KiB
C
|
|
/*
|
|
* O2EM Freeware Odyssey2 / Videopac+ Emulator
|
|
*
|
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
|
*
|
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
|
*
|
|
* http://o2em.sourceforge.net
|
|
*
|
|
*
|
|
*
|
|
* O2 audio emulation
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "cpu.h"
|
|
#include "types.h"
|
|
#include "config.h"
|
|
#include "vmachine.h"
|
|
#include "audio.h"
|
|
|
|
//#define SAMPLE_RATE 44100
|
|
#define PERIOD1 11 //11
|
|
#define PERIOD2 44 //44
|
|
|
|
#define SOUND_BUFFER_LEN 1056
|
|
|
|
#define AUD_CTRL 0xAA
|
|
#define AUD_D0 0xA7
|
|
#define AUD_D1 0xA8
|
|
#define AUD_D2 0xA9
|
|
|
|
|
|
int sound_IRQ;
|
|
//static short *stream=NULL;
|
|
//static AUDIOSTREAM *stream=NULL;
|
|
//FILE *sndlog=NULL;
|
|
|
|
static double flt_a=0.0, flt_b=0.0;
|
|
static unsigned char flt_prv = 0;
|
|
|
|
|
|
static void filter(unsigned char *buf, unsigned long len);
|
|
|
|
|
|
//void audio_process(unsigned char *buffer){
|
|
#ifdef GP32
|
|
void audio_process(unsigned short *buffer, int len)
|
|
#else
|
|
void audio_process(short *buffer, int len)
|
|
#endif
|
|
{
|
|
unsigned long aud_data;
|
|
#ifdef GP32
|
|
unsigned short s;
|
|
#else
|
|
short s;
|
|
#endif
|
|
int volume, re_circ, noise, enabled, intena, period, pnt, cnt, rndbit, pos;
|
|
|
|
aud_data = (VDCwrite[AUD_D2] | (VDCwrite[AUD_D1] << 8) | (VDCwrite[AUD_D0] << 16));
|
|
|
|
intena = VDCwrite[0xA0] & 0x04;
|
|
|
|
pnt = cnt = 0;
|
|
|
|
noise = VDCwrite[AUD_CTRL] & 0x10;
|
|
enabled = VDCwrite[AUD_CTRL] & 0x80;
|
|
rndbit = (enabled && noise) ? (rand()%2) : 0;
|
|
|
|
while (pnt < len/*SOUND_BUFFER_LEN*/) {
|
|
pos = (tweakedaudio) ? (pnt/3) : (MAXLINES-1);
|
|
volume = AudioVector[pos] & 0x0F;
|
|
enabled = AudioVector[pos] & 0x80;
|
|
period = (AudioVector[pos] & 0x20) ? PERIOD1 : PERIOD2;
|
|
re_circ = AudioVector[pos] & 0x40;
|
|
|
|
#ifdef GP32
|
|
s= ( (enabled) ? ((aud_data & 0x01)^rndbit) * (0x10 * volume) : 0) << 8;
|
|
#else
|
|
s= (( (enabled) ? ((aud_data & 0x01)^rndbit) * (0x10 * volume) : 0) - 128) << 8 ;
|
|
#endif
|
|
*buffer++ = s;
|
|
*buffer++ = s;
|
|
pnt++;
|
|
cnt++;
|
|
|
|
if (cnt >= period) {
|
|
cnt=0;
|
|
aud_data = (re_circ) ? ((aud_data >> 1) | ((aud_data & 1) << 23)) : (aud_data >>= 1);
|
|
rndbit = (enabled && noise) ? (rand()%2) : 0;
|
|
|
|
if (enabled && intena && (!sound_IRQ)) {
|
|
sound_IRQ = 1;
|
|
ext_IRQ();
|
|
}
|
|
}
|
|
}
|
|
|
|
// if (app_data.filter) filter(buffer, SOUND_BUFFER_LEN);
|
|
}
|
|
|
|
|
|
void update_audio(void) {
|
|
// unsigned char *p;
|
|
if (app_data.sound_en) {
|
|
// p = (unsigned char *)get_audio_stream_buffer(stream);
|
|
// if (p) {
|
|
// audio_process(p);
|
|
// if (sndlog) fwrite(p,1,SOUND_BUFFER_LEN,sndlog);
|
|
// free_audio_stream_buffer(stream);
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
void init_audio(void) {
|
|
// int i;
|
|
|
|
sound_IRQ=0;
|
|
// set_volume(255,255);
|
|
init_sound_stream();
|
|
|
|
// sndlog = NULL;
|
|
}
|
|
|
|
|
|
void init_sound_stream(void){
|
|
int vol;
|
|
if (app_data.sound_en){
|
|
if (app_data.filter)
|
|
vol = (255*app_data.svolume)/100;
|
|
else
|
|
vol = (255*app_data.svolume)/200;
|
|
// stream = play_audio_stream(SOUND_BUFFER_LEN,8,0,SAMPLE_RATE,vol,128);
|
|
// if (!stream) {
|
|
// printf("Error creating audio stream!\n");
|
|
// app_data.sound_en=0;
|
|
// }
|
|
flt_a = flt_b = 0.0;
|
|
flt_prv = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void mute_audio(void){
|
|
if (app_data.sound_en /*&& stream*/){
|
|
// stop_audio_stream(stream);
|
|
// stream=NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void close_audio(void) {
|
|
if (app_data.sound_en /*&& stream*/) {
|
|
// stop_audio_stream(stream);
|
|
}
|
|
app_data.sound_en=0;
|
|
}
|
|
|
|
|
|
static void filter(unsigned char *buffer, unsigned long len){
|
|
static unsigned char buf[SOUND_BUFFER_LEN];
|
|
int t;
|
|
unsigned long i;
|
|
if (len>SOUND_BUFFER_LEN) return;
|
|
memcpy(buf,buffer,len);
|
|
for (i=0; i<len; i++){
|
|
t = (i==0)?(buf[0]-flt_prv):(buf[i]-buf[i-1]);
|
|
if (t) flt_b = (double)t;
|
|
flt_a += flt_b/4.0 - flt_a/80.0;
|
|
flt_b -= flt_b/4.0;
|
|
if ((flt_a>255.0)||(flt_a<-255.0)) flt_a=0.0;
|
|
buffer[i] = (unsigned char)((flt_a+255.0)/2.0);
|
|
}
|
|
flt_prv = buf[len-1];
|
|
}
|
|
|
|
|