Applied all mainline PCem commits;
Removed SCSI thread waiting (except after executing the READ SUBCHANNEL command, to alleviate the effects of READ SUBCHANNEL spam done by CD players).
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define NCoef 2
|
||||
|
||||
static __inline float low_iir(int i, float NewSample) {
|
||||
/* fc=350Hz */
|
||||
static inline float low_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.00049713569693400649,
|
||||
0.00099427139386801299,
|
||||
@@ -35,7 +33,8 @@ static __inline float low_iir(int i, float NewSample) {
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
static __inline float low_cut_iir(int i, float NewSample) {
|
||||
/* fc=350Hz */
|
||||
static inline float low_cut_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.96839970114733542000,
|
||||
-1.93679940229467080000,
|
||||
@@ -67,7 +66,8 @@ static __inline float low_cut_iir(int i, float NewSample) {
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
static __inline float high_iir(int i, float NewSample) {
|
||||
/* fc=3.5kHz */
|
||||
static inline float high_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.72248704753064896000,
|
||||
-1.44497409506129790000,
|
||||
@@ -98,7 +98,8 @@ static __inline float high_iir(int i, float NewSample) {
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
static __inline float high_cut_iir(int i, float NewSample) {
|
||||
/* fc=3.5kHz */
|
||||
static inline float high_cut_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.03927726802250377400,
|
||||
0.07855453604500754700,
|
||||
@@ -133,7 +134,8 @@ static __inline float high_cut_iir(int i, float NewSample) {
|
||||
#undef NCoef
|
||||
#define NCoef 2
|
||||
|
||||
static __inline float sb_iir(int i, float NewSample) {
|
||||
/* fc=3.2kHz */
|
||||
static inline float sb_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.03356837051492005100,
|
||||
0.06713674102984010200,
|
||||
@@ -155,7 +157,6 @@ static __inline float sb_iir(int i, float NewSample) {
|
||||
1.00000000000000000000,
|
||||
-0.64940759319751051000
|
||||
};*/
|
||||
|
||||
static float y[2][NCoef+1]; /* output samples */
|
||||
static float x[2][NCoef+1]; /* input samples */
|
||||
int n;
|
||||
@@ -180,7 +181,8 @@ static __inline float sb_iir(int i, float NewSample) {
|
||||
#undef NCoef
|
||||
#define NCoef 2
|
||||
|
||||
static __inline float adgold_highpass_iir(int i, float NewSample) {
|
||||
/* fc=150Hz */
|
||||
static inline float adgold_highpass_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.98657437157334349000,
|
||||
-1.97314874314668700000,
|
||||
@@ -212,7 +214,8 @@ static __inline float adgold_highpass_iir(int i, float NewSample) {
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
static __inline float adgold_lowpass_iir(int i, float NewSample) {
|
||||
/* fc=150Hz */
|
||||
static inline float adgold_lowpass_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.00009159473951071446,
|
||||
0.00018318947902142891,
|
||||
@@ -244,7 +247,8 @@ static __inline float adgold_lowpass_iir(int i, float NewSample) {
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
static __inline float adgold_pseudo_stereo_iir(float NewSample) {
|
||||
/* fc=56Hz */
|
||||
static inline float adgold_pseudo_stereo_iir(float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.00001409030866231767,
|
||||
0.00002818061732463533,
|
||||
@@ -275,3 +279,69 @@ static __inline float adgold_pseudo_stereo_iir(float NewSample) {
|
||||
|
||||
return y[0];
|
||||
}
|
||||
|
||||
/* fc=3.2kHz - probably incorrect */
|
||||
static inline float dss_iir(float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.03356837051492005100,
|
||||
0.06713674102984010200,
|
||||
0.03356837051492005100
|
||||
};
|
||||
|
||||
float BCoef[NCoef+1] = {
|
||||
1.00000000000000000000,
|
||||
-1.41898265221812010000,
|
||||
0.55326988968868285000
|
||||
};
|
||||
|
||||
static float y[NCoef+1]; /* output samples */
|
||||
static float x[NCoef+1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for(n=NCoef; n>0; n--) {
|
||||
x[n] = x[n-1];
|
||||
y[n] = y[n-1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[0] = NewSample;
|
||||
y[0] = ACoef[0] * x[0];
|
||||
for(n=1; n<=NCoef; n++)
|
||||
y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];
|
||||
|
||||
return y[0];
|
||||
}
|
||||
|
||||
#undef NCoef
|
||||
#define NCoef 1
|
||||
/*Basic high pass to remove DC bias. fc=10Hz*/
|
||||
static inline float dac_iir(int i, float NewSample) {
|
||||
float ACoef[NCoef+1] = {
|
||||
0.99901119820285345000,
|
||||
-0.99901119820285345000
|
||||
};
|
||||
|
||||
float BCoef[NCoef+1] = {
|
||||
1.00000000000000000000,
|
||||
-0.99869185905052738000
|
||||
};
|
||||
|
||||
static float y[2][NCoef+1]; /* output samples */
|
||||
static float x[2][NCoef+1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for(n=NCoef; n>0; n--) {
|
||||
x[i][n] = x[i][n-1];
|
||||
y[i][n] = y[i][n-1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[i][0] = NewSample;
|
||||
y[i][0] = ACoef[0] * x[i][0];
|
||||
for(n=1; n<=NCoef; n++)
|
||||
y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n];
|
||||
|
||||
return y[i][0];
|
||||
}
|
||||
|
||||
119
src/sound/snd_lpt_dac.c
Normal file
119
src/sound/snd_lpt_dac.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <stdlib.h>
|
||||
#include "../ibm.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "filters.h"
|
||||
#include "../lpt.h"
|
||||
#include "snd_lpt_dac.h"
|
||||
#include "sound.h"
|
||||
#include "../timer.h"
|
||||
|
||||
typedef struct lpt_dac_t
|
||||
{
|
||||
uint8_t dac_val_l, dac_val_r;
|
||||
|
||||
int is_stereo;
|
||||
int channel;
|
||||
|
||||
int16_t buffer[2][SOUNDBUFLEN];
|
||||
int pos;
|
||||
} lpt_dac_t;
|
||||
|
||||
static void dac_update(lpt_dac_t *lpt_dac)
|
||||
{
|
||||
for (; lpt_dac->pos < sound_pos_global; lpt_dac->pos++)
|
||||
{
|
||||
lpt_dac->buffer[0][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_l ^ 0x80) * 0x40;
|
||||
lpt_dac->buffer[1][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_r ^ 0x80) * 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dac_write_data(uint8_t val, void *p)
|
||||
{
|
||||
lpt_dac_t *lpt_dac = (lpt_dac_t *)p;
|
||||
|
||||
timer_clock();
|
||||
|
||||
if (lpt_dac->is_stereo)
|
||||
{
|
||||
if (lpt_dac->channel)
|
||||
lpt_dac->dac_val_r = val;
|
||||
else
|
||||
lpt_dac->dac_val_l = val;
|
||||
}
|
||||
else
|
||||
lpt_dac->dac_val_l = lpt_dac->dac_val_r = val;
|
||||
dac_update(lpt_dac);
|
||||
}
|
||||
|
||||
static void dac_write_ctrl(uint8_t val, void *p)
|
||||
{
|
||||
lpt_dac_t *lpt_dac = (lpt_dac_t *)p;
|
||||
|
||||
if (lpt_dac->is_stereo)
|
||||
lpt_dac->channel = val & 0x01;
|
||||
}
|
||||
|
||||
static uint8_t dac_read_status(void *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void dac_get_buffer(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
lpt_dac_t *lpt_dac = (lpt_dac_t *)p;
|
||||
int c;
|
||||
|
||||
dac_update(lpt_dac);
|
||||
|
||||
for (c = 0; c < len; c++)
|
||||
{
|
||||
buffer[c*2] += dac_iir(0, lpt_dac->buffer[0][c]);
|
||||
buffer[c*2 + 1] += dac_iir(1, lpt_dac->buffer[1][c]);
|
||||
}
|
||||
lpt_dac->pos = 0;
|
||||
}
|
||||
|
||||
static void *dac_init()
|
||||
{
|
||||
lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t));
|
||||
memset(lpt_dac, 0, sizeof(lpt_dac_t));
|
||||
|
||||
sound_add_handler(dac_get_buffer, lpt_dac);
|
||||
|
||||
return lpt_dac;
|
||||
}
|
||||
static void *dac_stereo_init()
|
||||
{
|
||||
lpt_dac_t *lpt_dac = dac_init();
|
||||
|
||||
lpt_dac->is_stereo = 1;
|
||||
|
||||
return lpt_dac;
|
||||
}
|
||||
static void dac_close(void *p)
|
||||
{
|
||||
lpt_dac_t *lpt_dac = (lpt_dac_t *)p;
|
||||
|
||||
free(lpt_dac);
|
||||
}
|
||||
|
||||
lpt_device_t lpt_dac_device =
|
||||
{
|
||||
"LPT DAC / Covox Speech Thing",
|
||||
dac_init,
|
||||
dac_close,
|
||||
dac_write_data,
|
||||
dac_write_ctrl,
|
||||
dac_read_status
|
||||
};
|
||||
lpt_device_t lpt_dac_stereo_device =
|
||||
{
|
||||
"Stereo LPT DAC",
|
||||
dac_stereo_init,
|
||||
dac_close,
|
||||
dac_write_data,
|
||||
dac_write_ctrl,
|
||||
dac_read_status
|
||||
};
|
||||
2
src/sound/snd_lpt_dac.h
Normal file
2
src/sound/snd_lpt_dac.h
Normal file
@@ -0,0 +1,2 @@
|
||||
extern lpt_device_t lpt_dac_device;
|
||||
extern lpt_device_t lpt_dac_stereo_device;
|
||||
115
src/sound/snd_lpt_dss.c
Normal file
115
src/sound/snd_lpt_dss.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <stdlib.h>
|
||||
#include "../ibm.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "filters.h"
|
||||
#include "../lpt.h"
|
||||
#include "snd_lpt_dss.h"
|
||||
#include "sound.h"
|
||||
#include "../timer.h"
|
||||
|
||||
typedef struct dss_t
|
||||
{
|
||||
uint8_t fifo[16];
|
||||
int read_idx, write_idx;
|
||||
|
||||
uint8_t dac_val;
|
||||
|
||||
int time;
|
||||
|
||||
int16_t buffer[SOUNDBUFLEN];
|
||||
int pos;
|
||||
} dss_t;
|
||||
|
||||
static void dss_update(dss_t *dss)
|
||||
{
|
||||
for (; dss->pos < sound_pos_global; dss->pos++)
|
||||
dss->buffer[dss->pos] = (int8_t)(dss->dac_val ^ 0x80) * 0x40;
|
||||
}
|
||||
|
||||
|
||||
static void dss_write_data(uint8_t val, void *p)
|
||||
{
|
||||
dss_t *dss = (dss_t *)p;
|
||||
|
||||
timer_clock();
|
||||
|
||||
if ((dss->write_idx - dss->read_idx) < 16)
|
||||
{
|
||||
dss->fifo[dss->write_idx & 15] = val;
|
||||
dss->write_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dss_write_ctrl(uint8_t val, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
static uint8_t dss_read_status(void *p)
|
||||
{
|
||||
dss_t *dss = (dss_t *)p;
|
||||
|
||||
if ((dss->write_idx - dss->read_idx) >= 16)
|
||||
return 0x40;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void dss_get_buffer(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
dss_t *dss = (dss_t *)p;
|
||||
int c;
|
||||
|
||||
dss_update(dss);
|
||||
|
||||
for (c = 0; c < len*2; c += 2)
|
||||
{
|
||||
int16_t val = (int16_t)dss_iir((float)dss->buffer[c >> 1]);
|
||||
|
||||
buffer[c] += val;
|
||||
buffer[c+1] += val;
|
||||
}
|
||||
|
||||
dss->pos = 0;
|
||||
}
|
||||
|
||||
static void dss_callback(void *p)
|
||||
{
|
||||
dss_t *dss = (dss_t *)p;
|
||||
|
||||
dss_update(dss);
|
||||
|
||||
if ((dss->write_idx - dss->read_idx) > 0)
|
||||
{
|
||||
dss->dac_val = dss->fifo[dss->read_idx & 15];
|
||||
dss->read_idx++;
|
||||
}
|
||||
|
||||
dss->time += (TIMER_USEC * (1000000.0 / 7000.0));
|
||||
}
|
||||
|
||||
static void *dss_init()
|
||||
{
|
||||
dss_t *dss = malloc(sizeof(dss_t));
|
||||
memset(dss, 0, sizeof(dss_t));
|
||||
|
||||
sound_add_handler(dss_get_buffer, dss);
|
||||
timer_add(dss_callback, &dss->time, TIMER_ALWAYS_ENABLED, dss);
|
||||
|
||||
return dss;
|
||||
}
|
||||
static void dss_close(void *p)
|
||||
{
|
||||
dss_t *dss = (dss_t *)p;
|
||||
|
||||
free(dss);
|
||||
}
|
||||
|
||||
lpt_device_t dss_device =
|
||||
{
|
||||
"Disney Sound Source",
|
||||
dss_init,
|
||||
dss_close,
|
||||
dss_write_data,
|
||||
dss_write_ctrl,
|
||||
dss_read_status
|
||||
};
|
||||
1
src/sound/snd_lpt_dss.h
Normal file
1
src/sound/snd_lpt_dss.h
Normal file
@@ -0,0 +1 @@
|
||||
extern lpt_device_t dss_device;
|
||||
Reference in New Issue
Block a user