📄 output.c
字号:
//****************************************************************************//// OUTPUT.C - Performs output processing and playback of a PCM stream.//// Copyright (c) 1999,2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"#include "../hwport.h"#include "../hwdefs.h"#include "buffer/buffer.h"#include "tonectrl/tonectrl.h"#include "src/src.h"#include "twowire/twowire.h"#include "volume.h"#include "srs.h"#include "qsound.h"#include "spatial.h"#include "spectrum.h"//****************************************************************************//// If the address for the CS43L42/CS43L43 is defined, then do not use the// software volume and tone controls.////****************************************************************************#ifdef ADDR_CS43L43#undef SOFTWARE_TONE_CONTROL#undef SOFTWARE_VOLUME_CONTROL#endif//****************************************************************************//// The following table maps the volume setting of 0 through 20 to -96dB// through 0dB.////****************************************************************************#ifdef ADDR_CS43L43static const unsigned char ucVolumeMap[] = { 0xa0, 0xc3, 0xcc, 0xd2, 0xd7, 0xdc, 0xe0, 0xe3, 0xe6, 0xe9, 0xea, 0xee, 0xf0, 0xf3, 0xf5, 0xf7, 0xf9, 0xfa, 0xfc, 0xfe, 0xff };#endif//****************************************************************************//// The following structure contains the state variables for the output// processing routines.////****************************************************************************static struct{#ifdef SUPPORT_QSOUND // // The persistent state of the QSound control. // tQSoundControl sQSound;#endif#ifdef SUPPORT_SRS // // The persistent state of the SRS control. // tSRSControl sSRS;#endif#ifdef SUPPORT_SPATIALIZER // // The persistent state of the Spatializer control. // tSpatializerControl sSpatializer;#endif#ifdef SOFTWARE_TONE_CONTROL // // The persistent state of the software tone control. // tToneControl sTone;#endif#ifdef SOFTWARE_VOLUME_CONTROL // // The persistent state of the software volume control. // tVolumeControl sVolume;#endif#ifdef SUPPORT_SPECTRUM_ANALYZER // // The persistent state of the spectrum analyzer. // tSpectrumAnalyzer sSpectrum;#endif#ifdef ADDR_CS43L43 // // The current treble boost. // char cTrebleBoost; // // The current bass boost. // char cBassBoost; // // The current volume setting. // char cVolume; // // An unused byte to pad the next member to a word boundary. // unsigned char ucUnused;#endif // // The persistent state of the sample rate converter. // tSRC sSRC; // // The buffer to which we feed base rate samples. This will be used // directly for 44100Hz streams (plus 32000Hz and 48000Hz streams on the // EP73xx), or will be the output of the sample rate converter for all // other streams. // BufferState *pBaseRateBuffer; // // The buffer to which we send output data. // BufferState *pOutputBuffer; // // The buffers used for the sample rate converter's output data. // short sOutputLeft[384], sOutputRight[384];} sOutput;//****************************************************************************//// OutputInit initializes the output processing.////****************************************************************************voidOutputInit(void){ BufferState *psBuffer; // // Initialize the digital audio interface. // DAIInit(); psBuffer = DAIGetPlayBuffer();#ifdef SOFTWARE_VOLUME_CONTROL // // Initialize the volume control. // VolumeInit(&(sOutput.sVolume), psBuffer); psBuffer = VolumeGetInputBuffer(&(sOutput.sVolume));#endif#ifdef SUPPORT_SPECTRUM_ANALYZER // // Initialize the spectral analyzer. // SpectrumInit(&(sOutput.sSpectrum), psBuffer); psBuffer = SpectrumGetInputBuffer(&(sOutput.sSpectrum));#endif#ifdef SOFTWARE_TONE_CONTROL // // Initialize the tone controls. // ToneInit(&(sOutput.sTone), psBuffer); psBuffer = ToneGetInputBuffer(&(sOutput.sTone));#endif#ifdef SUPPORT_SRS // // Initialize the SRS control. // SRSInit(&(sOutput.sSRS), psBuffer); psBuffer = SRSGetInputBuffer(&(sOutput.sSRS));#endif#ifdef SUPPORT_QSOUND // // Initialize the QSound control. // QSoundInit(&(sOutput.sQSound), psBuffer); psBuffer = QSoundGetInputBuffer(&(sOutput.sQSound));#endif#ifdef SUPPORT_SPATIALIZER // // Initializer the Spatializer control. // SpatializerInit(&(sOutput.sSpatializer), psBuffer); psBuffer = SpatializerGetInputBuffer(&(sOutput.sSpatializer));#endif // // Save the pointer to the input buffer for the base rate stream. // sOutput.pBaseRateBuffer = psBuffer; // // For now, the output buffer is the buffer for base rate stream. // sOutput.pOutputBuffer = psBuffer;}//****************************************************************************//// OutputEnable initializes the output processing.////****************************************************************************voidOutputEnable(void){#ifdef HwPortABCD_DAC_Enable volatile unsigned long *pulPtr = (unsigned long *)HwBaseAddress;#endif#ifdef ADDR_CS43L43 unsigned long ulLoop;#endif // // There is nothing to do if the output is already enabled. // if(ulSystemFlags & SYSFLAG_OUTPUT_ENABLED) { return; } // // If the sample rate is a base rate (i.e. if the base rate buffer it not // the same as the output buffer), then enable the output processing // interrupt. // if(sOutput.pBaseRateBuffer != sOutput.pOutputBuffer) { // // Enable the output processing interupt. // DisableIRQ(); ulSystemFlags |= SYSFLAG_PROCESS_OUTPUT; EnableIRQ(); } // // Enable the DAC. //#ifdef HwPortABCD_DAC_Enable pulPtr[HwPortABCD >> 2] ^= HwPortABCD_DAC_Enable;#endif // // Enable the digital audio interface. // DAIEnable();#ifdef ADDR_CS43L43 // // Delay so the DAC can calibrate. // for(ulLoop = 0; ulLoop < 1024; ulLoop++) { } // // Configure the CS43L43. First, we must enable the control port on the // CS43L43 by setting the CP_EN bit (bit 0) of register 1. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x01, 0xd3); // // Now, enable the tone controls and limiter. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x0a, 0x39); // // Set the data format to left justified. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x0b, 0x02); // // Power on the DAC. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x01, 0xd1); // // Delay while the DAC initializes. // for(ulLoop = 0; ulLoop < 65536 * 32; ulLoop++) { } // // Write the current tone setting. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x06, (sOutput.cBassBoost << 4) | sOutput.cTrebleBoost); // // Write the treble boost corner frequency to 7kHz, the bass boost corner // frequency to 200Hz, and set the two channel volumes to be identical. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x07, 0xa8); // // Write the current volume setting. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x04, ucVolumeMap[(unsigned long)sOutput.cVolume]);#endif // // Indicate that the output is enabled. // DisableIRQ(); ulSystemFlags |= SYSFLAG_OUTPUT_ENABLED; EnableIRQ();}//****************************************************************************//// OutputDisable shuts down the output processing.////****************************************************************************voidOutputDisable(void){#ifdef HwPortABCD_DAC_Enable volatile unsigned long *pulPtr = (unsigned long *)HwBaseAddress;#endif BufferState *psBuffer; // // There is nothing to do if the output is already disabled. // if(!(ulSystemFlags & SYSFLAG_OUTPUT_ENABLED)) { return; } // // Make sure that all the input data has been processed. // psBuffer = sOutput.pOutputBuffer; while(!BufferIsEmpty(psBuffer)) { // // Put the EP7209 into HALT mode. // Halt(); } // // Disable the output processing interrupt. // DisableIRQ(); ulSystemFlags &= ~SYSFLAG_PROCESS_OUTPUT; EnableIRQ(); // // Wait until the the digital audio interface has completed playback. // psBuffer = DAIGetPlayBuffer(); while(!BufferIsEmpty(psBuffer)) { // // Put the EP7209 into HALT mode. // Halt(); }#ifdef ADDR_CS43L43 // // Power off the DAC. // TwoWireWrite((unsigned long *)(HwBaseAddress + HwPortABCD), (unsigned long *)(HwBaseAddress + HwDdrABCD), HwPortABCD_Clock, HwPortABCD_Data, ADDR_CS43L43, 0x01, 0xd3);#endif // // Disable the DAC. //#ifdef HwPortABCD_DAC_Enable pulPtr[HwPortABCD >> 2] ^= HwPortABCD_DAC_Enable;#endif // // Indicate that the output is disabled. // DisableIRQ(); ulSystemFlags &= ~SYSFLAG_OUTPUT_ENABLED; EnableIRQ(); // // Disable the digital audio interface if appropriate. // if(!(ulSystemFlags & (SYSFLAG_OUTPUT_ENABLED | SYSFLAG_INPUT_ENABLED))) { DAIDisable(); }}//****************************************************************************//// OutputGetInputBuffer returns a pointer to the input buffer for the output// processing.////****************************************************************************BufferState *OutputGetInputBuffer(void){ // // Return a pointer to the output buffer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -