void JERRYI2SCallback(void) { // We don't have to divide the RISC clock rate by this--the reason is a bit // convoluted. Will put explanation here later... // What's needed here is to find the ratio of the frequency to the number of // clock cycles in one second. For example, if the sample rate is 44100, we // divide the clock rate by this: 26590906 / 44100 = 602 cycles. // Which means, every 602 cycles that go by we have to generate an interrupt. jerryI2SCycles = 32 * (2 * (sclk + 1)); //This makes audio faster, but not enough and the pitch is wrong besides // jerryI2SCycles = 32 * (2 * (sclk - 1)); // If INTERNAL flag is set, then JERRY's SCLK is master if (smode & SMODE_INTERNAL) { // This does the 'IRQ enabled' checking... DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); // double usecs = (float)jerryI2SCycles * RISC_CYCLE_IN_USEC; //this fix is almost enough to fix timings in tripper, but not quite enough... double usecs = (float)jerryI2SCycles * (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC); SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY); } else { // This is handled in the BUTCH handler, where it should be... #if 0 // JERRY is slave to external word clock //Note that 44100 Hz requires samples every 22.675737 usec. //When JERRY is slave to the word clock, we need to do interrupts either at //44.1K sample rate or at a 88.2K sample rate (11.332... usec). /* // This is just a temporary kludge to see if the CD bus mastering works // I.e., this is totally faked...! // The whole interrupt system is pretty much borked and is need of an overhaul. // What we need is a way of handling these interrupts when they happen instead // of scanline boundaries the way it is now. jerry_i2s_interrupt_timer -= cycles; if (jerry_i2s_interrupt_timer <= 0) { //This is probably wrong as well (i.e., need to check enable lines)... !!! FIX !!! [DONE] if (ButchIsReadyToSend())//Not sure this is right spot to check... { // return GetWordFromButchSSI(offset, who); SetSSIWordsXmittedFromButch(); DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); } jerry_i2s_interrupt_timer += 602; }*/ if (ButchIsReadyToSend())//Not sure this is right spot to check... { // return GetWordFromButchSSI(offset, who); SetSSIWordsXmittedFromButch(); DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); } SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY); #endif } }
void JERRYResetPIT2(void) { RemoveCallback(JERRYPIT2Callback); if (JERRYPIT1Prescaler | JERRYPIT1Divider) { double usecs = (float)(JERRYPIT2Prescaler + 1) * (float)(JERRYPIT2Divider + 1) * RISC_CYCLE_IN_USEC; SetCallbackTime(JERRYPIT2Callback, usecs, EVENT_JERRY); } }
void JERRYI2SCallback(void) { // We don't have to divide the RISC clock rate by this--the reason is a bit // convoluted. Will put explanation here later... // What's needed here is to find the ratio of the frequency to the number of clock cycles // in one second. For example, if the sample rate is 44100, we divide the clock rate by // this: 26590906 / 44100 = 602 cycles. // Which means, every 602 cycles that go by we have to generate an interrupt. jerryI2SCycles = 32 * (2 * (*sclk + 1)); // If INTERNAL flag is set, then JERRY's SCLK is master if (*smode & SMODE_INTERNAL) { double usecs; // This does the 'IRQ enabled' checking... DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); // double usecs = (float)jerryI2SCycles * RISC_CYCLE_IN_USEC; //this fix is almost enough to fix timings in tripper, but not quite enough... usecs = (float)jerryI2SCycles * (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC); SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY); } else { // JERRY is slave to external word clock //Note that 44100 Hz requires samples every 22.675737 usec. //When JERRY is slave to the word clock, we need to do interrupts either at 44.1K //sample rate or at a 88.2K sample rate (11.332... usec). if (ButchIsReadyToSend())//Not sure this is right spot to check... { // return GetWordFromButchSSI(offset, who); SetSSIWordsXmittedFromButch(); DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); } SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY); } }
void SDLSoundCallback(void * userdata, uint16_t * buffer, int length) { // 1st, check to see if the DSP is running. If not, fill the buffer with L/RXTD and exit. if (!DSPIsRunning()) { for(int i=0; i<length; i+=2) { buffer[i + 0] = *ltxd; buffer[i + 1] = *rtxd; } return; } // The length of time we're dealing with here is 1/48000 s, so we multiply this // by the number of cycles per second to get the number of cycles for one sample. //uint32_t riscClockRate = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); //uint32_t cyclesPerSample = riscClockRate / DAC_AUDIO_RATE; // This is the length of time // timePerSample = (1000000.0 / (double)riscClockRate) * (); // Now, run the DSP for that length of time for each sample we need to make bufferIndex = 0; sampleBuffer = buffer; // If length is the length of the sample buffer in BYTES, then shouldn't the # of // samples be / 4? No, because we bump the sample count by 2, so this is OK. numberOfSamples = length; bufferDone = false; SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY); // These timings are tied to NTSC, need to fix that in event.cpp/h! [FIXED] do { double timeToNextEvent = GetTimeToNextEvent(EVENT_JERRY); if (vjs.DSPEnabled) { if (vjs.usePipelinedDSP) DSPExecP2(USEC_TO_RISC_CYCLES(timeToNextEvent)); else DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent)); } HandleNextEvent(EVENT_JERRY); } while (!bufferDone); }
void DSPSampleCallback(void) { ((uint16_t *)sampleBuffer)[bufferIndex + 0] = ltxd; ((uint16_t *)sampleBuffer)[bufferIndex + 1] = rtxd; bufferIndex += 2; if (bufferIndex == numberOfSamples) { bufferDone = true; return; } SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY); }