Audio recording can now about all audio rates ZSNES supports for PAL and NTSC at stereo. Audio writing buffering removed for now. Fixed bug when writing 32000Hz at PAL.

This commit is contained in:
n-a-c-h
2006-02-27 13:42:31 +00:00
parent 0bb0ee4075
commit a5211e5b27

View File

@@ -1848,21 +1848,26 @@ Code for dumping raw video
*/
#define RAW_BUFFER_SAMPLES 12800
#define RAW_WIDTH 256
#define RAW_HEIGHT 224
//NTSC FPS is 59.948743718592964824120603015060 in AVI that's a fraction of 59649/995
//which equals 59.948743718592964824120603015075, so videos should not desync for several millinium
//FPS = 64000 / Samples per Frame
//FPS = Rate*Stereo / Samples per Frame
//These two numbers help with calculating how many samples are needed per frame
//59.948743718592964824120603015060 = SAMPLE_NTSC_HI*32000/SAMPLE_NTSC_LO *2
#define SAMPLE_NTSC_HI 31840000ULL
//59.948743718592964824120603015060 = SAMPLE_NTSC_LO*Rate/SAMPLE_NTSC_HI
//Samples per Frame = SAMPLE_NTSC_HI/SAMPLE_NTSC_LO *Stereo
#define SAMPLE_NTSC_HI_SCALE 995ULL
#define SAMPLE_NTSC_LO 59649ULL
//Code using this by Bisqwit
//Used by raw videos for calculating sample rate in NTSC mode
//Code by Bisqwit
static const unsigned int freqtab[] = { 8000, 11025, 22050, 44100, 16000, 32000, 48000 };
extern unsigned int SoundQuality;
#define RATE freqtab[SoundQuality]
//0 = None; 1 Logging, but not now, 2 Log now
@@ -1926,8 +1931,6 @@ struct
FILE *vp;
FILE *ap;
unsigned short *sample_buffer;
size_t sample_index;
size_t aud_dsize_pos;
//These next three are only used for NTSC videos to keep sample rate correct
@@ -1955,17 +1958,7 @@ static void raw_video_close()
if (raw_vid.ap)
{
if (raw_vid.sample_buffer)
{
size_t file_size;
if (raw_vid.sample_index)
{
fwrite(raw_vid.sample_buffer, 2, raw_vid.sample_index, raw_vid.ap); //Sample is 2 bytes
}
free(raw_vid.sample_buffer);
file_size = ftell(raw_vid.ap); //Get file size
size_t file_size = ftell(raw_vid.ap); //Get file size
if (!fseek(raw_vid.ap, 4, SEEK_SET)) //Seek to after RIFF header
{
fwrite4(file_size - 8, raw_vid.ap); //Don't include header or this write, -8
@@ -1978,7 +1971,6 @@ static void raw_video_close()
}
fclose(raw_vid.ap);
raw_vid.ap = 0;
}
AudioLogging = 0;
}
}
@@ -2013,8 +2005,6 @@ static bool raw_video_open()
if (!MovieVideoMode || raw_vid.vp)
{
if ((raw_vid.ap = fopen(md_pcm_audio, "wb")))
{
if ((raw_vid.sample_buffer = (unsigned short *)malloc(RAW_BUFFER_SAMPLES*sizeof(short))))
{
fputs("RIFF", raw_vid.ap); //header
fwrite4(~0, raw_vid.ap); //file size - unknown till file close
@@ -2022,8 +2012,8 @@ static bool raw_video_open()
fwrite4(0x12, raw_vid.ap); //fmt size
fwrite2(1, raw_vid.ap); //fmt type (PCM)
fwrite2(2, raw_vid.ap); //channels
fwrite4(32000, raw_vid.ap); //sample rate
fwrite4(32000*4, raw_vid.ap); //byte rate (sample rate*block align)
fwrite4(RATE, raw_vid.ap); //sample rate
fwrite4(RATE*4, raw_vid.ap); //byte rate (sample rate*block align)
fwrite2(16/8*2, raw_vid.ap); //block align (SignificantBitsPerSample / 8 * NumChannels)
fwrite2(16, raw_vid.ap); //Significant bits per sample
fwrite2(0, raw_vid.ap); //Extra format bytes
@@ -2033,20 +2023,49 @@ static bool raw_video_open()
if (!romispal)
{
raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI;
raw_vid.sample_ntsc_hi = SAMPLE_NTSC_HI_SCALE*RATE;
raw_vid.sample_ntsc_lo = SAMPLE_NTSC_LO;
raw_vid.sample_ntsc_balance = SAMPLE_NTSC_HI;
raw_vid.sample_ntsc_balance = raw_vid.sample_ntsc_hi;
}
AudioLogging = 1;
return(true);
}
}
}
raw_video_close();
return(false);
}
static void raw_audio_write(unsigned int samples)
{
void ProcessSoundBuffer();
extern int DSPBuffer[1280];
extern unsigned int BufferSizeB, BufferSizeW;
unsigned int i = 0;
int temp;
if (samples > 1280)
{
raw_audio_write(1280);
samples -= 1280;
}
BufferSizeB = samples;
BufferSizeW = samples<<1;
AudioLogging = 2;
asm_call(ProcessSoundBuffer);
AudioLogging = 1;
for (i = 0; i < BufferSizeB; i++)
{
temp = DSPBuffer[i];
if (temp > 32767) { temp = 32767; }
else if (temp < -32768) { temp =-32768; }
fwrite2((short)temp, raw_vid.ap);
}
}
#define PIXEL (vidbuffer[(i*288) + j + 16])
static void raw_video_write_frame()
{
@@ -2067,45 +2086,26 @@ static void raw_video_write_frame()
if (raw_vid.ap)
{
void ProcessSoundBuffer();
extern int DSPBuffer[1280];
extern unsigned int BufferSizeB, BufferSizeW;
unsigned int i = 0;
int temp;
unsigned int samples;
if (romispal)
{
BufferSizeB = 1280;
samples = RATE*2/50;
if (samples & 1)
{
static signed char odd_carry = 0;
samples += odd_carry-1;
odd_carry ^= 2;
}
}
else
{
//Thanks Bisqwit for this algorithm
BufferSizeB = (raw_vid.sample_ntsc_balance/raw_vid.sample_ntsc_lo) << 1;
samples = (raw_vid.sample_ntsc_balance/raw_vid.sample_ntsc_lo) << 1;
raw_vid.sample_ntsc_balance %= raw_vid.sample_ntsc_lo;
raw_vid.sample_ntsc_balance += raw_vid.sample_ntsc_hi;
//printf("Frame %u: %u samples\n", raw_vid.frame_index, BufferSizeB);
}
BufferSizeW = BufferSizeB<<1;
AudioLogging = 2;
asm_call(ProcessSoundBuffer);
AudioLogging = 1;
for (i = 0; i < BufferSizeB; i++)
{
temp = DSPBuffer[i];
if (temp > 32767) { temp = 32767; }
else if (temp < -32768) { temp =-32768; }
raw_vid.sample_buffer[raw_vid.sample_index] = temp;
raw_vid.sample_index++;
if (raw_vid.sample_index == RAW_BUFFER_SAMPLES)
{
fwrite(raw_vid.sample_buffer, 2, RAW_BUFFER_SAMPLES, raw_vid.ap); //Each sample is 2 bytes
raw_vid.sample_index = 0;
}
//printf("Frame %u: %u samples\n", raw_vid.sample_index, BufferSizeB);
}
raw_audio_write(samples);
}
}