host sample rate support for Pico

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@445 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-05-12 20:17:32 +00:00
parent ef4eb506de
commit ed367a3f7c
5 changed files with 49 additions and 23 deletions

View file

@ -71,7 +71,7 @@ extern int (*PicoMCDcloseTray)(void);
extern int PicoCDBuffers;
// Pico/Pico.c
#define XPCM_BUFFER_SIZE (320+32)
#define XPCM_BUFFER_SIZE (320+160)
typedef struct
{
int pen_pos[2];

View file

@ -8,6 +8,14 @@ picohw_state PicoPicohw;
static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
static int fifo_bytes_line = (16000<<16)/60/262/2; // fifo bytes/line. FIXME: other rates, modes
PICO_INTERNAL void PicoReratePico(void)
{
if (Pico.m.pal)
fifo_bytes_line = (16000<<16)/50/312/2;
else fifo_bytes_line = (16000<<16)/60/262/2;
PicoPicoPCMRerate();
}
static void PicoLinePico(int count)
{
PicoPicohw.line_counter += count;

View file

@ -15,7 +15,7 @@
else if ( val < min ) val = min; \
}
const int TableQuant[8] =
static const int TableQuant[8] =
{
ADFIX(0.8984375),
ADFIX(0.8984375),
@ -29,17 +29,24 @@ const int TableQuant[8] =
// changed using trial and error..
//const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15 };
const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, -1, -1, -3, -5, -7, -9, -11, -13, -15 };
static const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, -1, -1, -3, -5, -7, -9, -11, -13, -15 };
static int sample = 0, quant = 0, sgn = 0;
static int stepsamples = (44100<<10)/16000;
static int sample = 0, quant = 0;
PICO_INTERNAL void PicoPicoPCMReset(void)
{
sample = 0;
sample = sgn = 0;
quant = 0x7f;
memset(PicoPicohw.xpcm_buffer, 0, sizeof(PicoPicohw.xpcm_buffer));
}
PICO_INTERNAL void PicoPicoPCMRerate(void)
{
stepsamples = (PsndRate<<10)/16000;
}
#define XSHIFT 7
#define do_sample() \
@ -47,24 +54,16 @@ PICO_INTERNAL void PicoPicoPCMReset(void)
sample += quant * quant_mul[srcval] >> XSHIFT; \
quant = (quant * TableQuant[srcval&7]) >> ADPCMSHIFT; \
Limit(quant, 0x6000, 0x7f); \
Limit(sample, 32767, -32768); \
Limit(sample, 32767/2, -32768/2); \
}
PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
{
unsigned char *src = PicoPicohw.xpcm_buffer;
unsigned char *lim = PicoPicohw.xpcm_ptr;
int srcval, stepsamples = (44100<<10)/16000, needsamples = 0; // TODO: stepsamples
int srcval, needsamples = 0;
if (src == lim)
{
if (stereo)
// still must expand SN76496 to stereo
for (; length > 0; buffer+=2, length--)
buffer[1] = buffer[0];
sample = quant = 0;
return;
}
if (src == lim) goto end;
for (; length > 0 && src < lim; src++)
{
@ -72,7 +71,7 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
do_sample();
for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
*buffer++ = sample;
*buffer++ += sample;
if (stereo) { buffer[0] = buffer[-1]; buffer++; }
}
@ -80,9 +79,13 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
do_sample();
for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
*buffer++ = sample;
*buffer++ += sample;
if (stereo) { buffer[0] = buffer[-1]; buffer++; }
}
// lame normalization stuff, needed due to wrong adpcm algo
sgn += (sample < 0) ? -1 : 1;
if (sgn < -16 || sgn > 16) sample -= sample >> 5;
}
if (src < lim) {
@ -90,11 +93,21 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
memmove(PicoPicohw.xpcm_buffer, src, di);
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer + di;
elprintf(EL_STATUS, "xpcm update: over %i", di);
}
else
{
elprintf(EL_STATUS, "xpcm update: under %i", length);
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
}
// adjust fifo
PicoPicohw.fifo_bytes = di;
return;
}
elprintf(EL_STATUS, "xpcm update: under %i", length);
PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
end:
if (stereo)
// still must expand SN76496 to stereo
for (; length > 0; buffer+=2, length--)
buffer[1] = buffer[0];
sample = sgn = 0;
quant = 0x7f;
}

View file

@ -443,10 +443,12 @@ PICO_INTERNAL int PicoFrameMCD(void);
// Pico/Pico.c
PICO_INTERNAL int PicoInitPico(void);
PICO_INTERNAL void PicoReratePico(void);
// Pico/xpcm.c
PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo);
PICO_INTERNAL void PicoPicoPCMReset(void);
PICO_INTERNAL void PicoPicoPCMRerate(void);
// Sek.c
PICO_INTERNAL int SekInit(void);

View file

@ -158,6 +158,9 @@ void PsndRerate(int preserve_state)
// set mixer
PsndMix_32_to_16l = (PicoOpt & POPT_EN_STEREO) ? mix_32_to_16l_stereo : mix_32_to_16_mono;
if (PicoAHW & PAHW_PICO)
PicoReratePico();
}