/*
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
* This file is part of FBZX
*
* FBZX 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 3 of the License, or
* (at your option) any later version.
*
* FBZX 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, see .
*
*/
#include "z80free/Z80free.h"
#include "computer.h"
#include "emulator.h"
#include
#include
#include
char tabla[1024];
#include
#ifndef GEKKO
#include
#endif
#ifdef DEBUG
extern FILE *fdebug;
#define printf(...) fprintf(fdebug,__VA_ARGS__)
#else
#ifdef GEKKO
#define printf(...)
#endif
#endif
/*#include
#include "SDL/SDL_audio.h"
#include "SDL_thread.h"*/
#include "sound.h"
#ifdef D_SOUND_OSS
#include
int audio_fd;
#endif
#ifdef D_SOUND_ALSA
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include
int started_sound;
snd_pcm_t * _soundDevice;
#endif
#ifdef D_SOUND_PULSE
#include
pa_simple *pulse_s;
#endif
#ifdef GEKKO
#include
#endif
enum e_soundtype sound_type;
int sound_init() {
if (sound_type!=SOUND_AUTOMATIC) {
switch(sound_type) {
case SOUND_NO: // No sound; simulate 8bits mono
printf("No Sound\n");
ordenador.sign=0;
ordenador.format=0;
ordenador.channels=1;
ordenador.channels = 1;
ordenador.freq=48000;
ordenador.buffer_len=4800; // will wait 1/10 second
return (0);
break;
#ifdef D_SOUND_PULSE
case SOUND_PULSEAUDIO:
printf("Trying PulseAudio\n");
if(0==sound_init_pulse()) {
sound_type=SOUND_PULSEAUDIO;
return 0;
} else {
printf("Failed\n");
return -1;
}
break;
#endif
#ifdef D_SOUND_ALSA
case SOUND_ALSA:
printf("Trying ALSA sound\n");
if(0==sound_init_alsa()) {
sound_type=SOUND_ALSA;
return 0;
} else {
printf("Failed\n");
return -1;
}
break;
#endif
#ifdef D_SOUND_OSS
case SOUND_OSS:
printf("Trying OSS sound\n");
if(0==sound_init_oss()) {
sound_type=SOUND_OSS;
return 0;
} else {
printf("Failed\n");
return -1;
}
break;
#endif
#ifdef GEKKO
case SOUND_ASND:
printf("Trying ASND sound\n");
if(0==sound_init_asnd()) {
sound_type=SOUND_ASND;
return 0;
} else {
printf("Failed\n");
return -1;
}
break;
#endif
default:
break;
}
}
#ifdef D_SOUND_PULSE
printf("Trying PulseAudio\n");
if(0==sound_init_pulse()) {
sound_type=SOUND_PULSEAUDIO;
return 0;
}
#endif
#ifdef D_SOUND_ALSA
printf("Trying ALSA sound\n");
if(0==sound_init_alsa()) {
sound_type=SOUND_ALSA;
return 0;
}
#endif
#ifdef D_SOUND_OSS
printf("Trying OSS sound\n");
if(0==sound_init_oss()) {
sound_type=SOUND_OSS;
return 0;
}
#endif
#ifdef GEKKO
printf("Trying ASND sound\n");
if(0==sound_init_asnd()) {
sound_type=SOUND_ASND;
return 0;
}
#endif
return -1;
}
#ifdef GEKKO
int sound_init_asnd() {
ASND_Init();
ASND_Pause(0);
ordenador.sign=0;
ordenador.format=0;
ordenador.channels=1;
ordenador.freq=48000;
ordenador.buffer_len=4096;
return 0;
}
#endif
#ifdef D_SOUND_PULSE
int sound_init_pulse() {
pa_sample_spec ss;
pa_buffer_attr buf;
ss.format = PA_SAMPLE_U8;
ss.channels = 1;
ss.rate = 48000;
buf.maxlength=8192;
buf.tlength=4096;
buf.prebuf=4096;
buf.minreq=4096;
buf.fragsize=4096;
pulse_s = pa_simple_new(NULL,"fbzx",PA_STREAM_PLAYBACK,NULL,"Spectrum",&ss,NULL,&buf,NULL);
if (pulse_s==NULL) {
return -1;
}
ordenador.sign=0;
ordenador.format=0;
ordenador.channels=1;
ordenador.freq=48000;
ordenador.buffer_len=4096;
return 0;
}
#endif
#ifdef D_SOUND_ALSA
int sound_init_alsa() {
int err;
snd_pcm_hw_params_t *hw_params;
unsigned int resample,samplerate;
snd_pcm_uframes_t bufferSize;
err = snd_pcm_open( &_soundDevice, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0 );
if (err<0) {
return -1;
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
snd_pcm_close (_soundDevice);
return -2;
}
if ((err = snd_pcm_hw_params_any (_soundDevice, hw_params)) < 0) {
snd_pcm_close (_soundDevice);
return -2;
}
if ((err = snd_pcm_hw_params_set_access (_soundDevice, hw_params,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
snd_pcm_close (_soundDevice);
return -3;
}
if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U8) >= 0) {
ordenador.sign=0;
ordenador.format=0;
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S8) >= 0) {
ordenador.sign=-128;
ordenador.format=0;
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U16_LE) >= 0) {
ordenador.sign=0;
ordenador.format=1;
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S16_LE) >= 0) {
ordenador.sign=-128;
ordenador.format=1;
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U16_BE) >= 0) {
ordenador.sign=0;
ordenador.format=2;
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S16_BE) >= 0) {
ordenador.sign=-128;
ordenador.format=2;
} else {
snd_pcm_close (_soundDevice);
return -3;
}
// Disable resampling.
resample = 0;
err = snd_pcm_hw_params_set_rate_resample(_soundDevice, hw_params, resample);
if (err < 0) {
snd_pcm_close (_soundDevice);
return -3;
}
if ((err = snd_pcm_hw_params_set_channels (_soundDevice, hw_params, 1)) >= 0) {
ordenador.channels=1;
} else if ((err = snd_pcm_hw_params_set_channels (_soundDevice, hw_params, 2)) >= 0) {
ordenador.channels=2;
} else {
snd_pcm_close (_soundDevice);
return -3;
}
samplerate=48000;
if ((err = snd_pcm_hw_params_set_rate_near (_soundDevice, hw_params, &samplerate, 0)) < 0) {
snd_pcm_close (_soundDevice);
return -3;
}
bufferSize=4096;
if (snd_pcm_hw_params_set_buffer_size_near(_soundDevice, hw_params, &bufferSize) < 0) {
fprintf(stderr, "Error setting buffersize.\n");
return -3;
}
ordenador.freq=samplerate;
err = snd_pcm_hw_params (_soundDevice, hw_params);
if (err<0) {
return -3;
}
//snd_pcm_hw_params_get_buffer_size( hw_params, &bufferSize );
ordenador.buffer_len=bufferSize;
started_sound=0;
return 0;
err = snd_pcm_prepare (_soundDevice);
if (err<0) {
return -5;
}
return 0;
}
#endif
#ifdef D_SOUND_OSS
int sound_init_oss() {
int parameter;
int parameter2;
int bytes,stereo;
int retval;
audio_buf_info bi;
audio_fd=open("/dev/dsp",O_WRONLY); // open DSP
if(audio_fd==-1) {
return (-1);
}
ordenador.sign=0;
ordenador.format=0;
bytes=1;
ordenador.channels=1;
ordenador.freq=22050;
ordenador.buffer_len=2048/(ordenador.channels*bytes);
parameter=0x0002000C ; // two buffers with 4096 bytes each one
if(ioctl(audio_fd,SNDCTL_DSP_SETFRAGMENT, ¶meter)==-1)
return (-6);
// set format
if(ioctl(audio_fd,SNDCTL_DSP_GETFMTS, ¶meter2)==-1)
return (-2);
parameter = 2; // we want mono audio
if(ioctl(audio_fd,SNDCTL_DSP_CHANNELS, ¶meter)==-1)
return (-4);
ordenador.channels = parameter;
// Priority: U8, S8, U16LE, S16LE, U16BE, U16LE
if(parameter2 & AFMT_S16_BE) {
parameter = AFMT_S16_BE;
}
if(parameter2 & AFMT_U16_BE){
parameter = AFMT_U16_BE;
}
if(parameter2 & AFMT_S16_LE) {
parameter = AFMT_S16_LE;
}
if(parameter2 & AFMT_U16_LE) {
parameter = AFMT_U16_LE;
}
if(parameter2 & AFMT_S8) {
parameter = AFMT_S8;
}
if(parameter2 & AFMT_U8) {
parameter = AFMT_U8;
}
bytes=0; //8 bits
stereo=0; // no stereo
retval=ioctl(audio_fd,SNDCTL_DSP_SETFMT,¶meter);
if(retval != 0) {
return (-3);
}
switch(parameter) {
case AFMT_U8:
ordenador.sign=0;
ordenador.format=0;
bytes=1;
break;
case AFMT_S8:
ordenador.sign=-128;
ordenador.format=0;
bytes=1;
break;
case AFMT_U16_LE:
ordenador.sign=0;
ordenador.format=1;
bytes=2;
break;
case AFMT_S16_LE:
ordenador.sign=-128;
ordenador.format=1;
bytes=2;
break;
case AFMT_U16_BE:
ordenador.sign=0;
ordenador.format=2;
bytes=2;
break;
case AFMT_S16_BE:
ordenador.sign=-128;
ordenador.format=2;
bytes=2;
break;
}
parameter=48000; // we want, by default, 48000 samples per second
if(ioctl(audio_fd,SNDCTL_DSP_SPEED, ¶meter)==-1)
return (-5);
ordenador.freq=parameter;
if(ioctl(audio_fd,SNDCTL_DSP_GETOSPACE, &bi)==-1)
return (-6);
parameter=bi.bytes/4;
ordenador.buffer_len=parameter/(ordenador.channels*bytes);
return(0);
}
#endif
void sound_remove_dc(unsigned char *sound_buffer,int size){
static float oldsample=0.0;
static float origsample;
static int i;
for (i=0;i