/* * srcmgr.c -- ESS Technology allegro audio driver. * * Copyright (C) 1992-2000 Don Kim (don.kim@esstech.com) * */ #include "hckernel.h" static int num_errors = 0; /* Dummy variable used to supress lint warnings. */ #define DMAREC /*/////////////////////////////////////////////////////////////////////////// */ /* DSP kernel support */ /* index 0 - 44.1k; 1 - 32k; 2 - 22.05k; 3 - 11.025k; 4 - 8k */ /* */ /*/////////////////////////////////////////////////////////////////////////// */ WORD gwSRC3_PB_SIZE_OUT[5] = { 37 * 2 * 2, 6 * 2, 37 * 2 * 2, 26 * 2, 12 * 2 }; WORD gwSRC3_PB_SIZE_IN[5] = { 34 * 2, 4, 17 * 2, 6, 2 }; WORD gwSRC3_PB_FILTER_LENGTH[5] = { 666, 60, 666, 338, 360 }; WORD gwSRC3_PB_FILTER_TAP_SIZE[5] = { 17, 19, 17, 25, 59 }; /* SIZE - 1 */ WORD gwSRC3_PB_BIG_LOOP_COUNTER[5] = { 11, 1, 5, 2, 0 }; WORD gwSRC3_PB_SMALL_LOOP_COUNTER[5] = { 0, 0, 1, 3, 4 }; WORD gwSRC3_IN_BufferSize[5] = { 2 * 17 * 16, 192 * 2, 2 * 17 * 16, 192 * 2, 192 * 2 }; WORD gwSRC3_OUT_BufferSize[5] = { 160 * 4, 160 * 2, 160 * 4, 160 * 2, 160 * 2 }; WORD gwSRC3_REC_SIZE_OUT[5] = { 34 * 2, 4, 12, 6, 2 }; WORD gwSRC3_REC_SIZE_IN[5] = { 37 * 2, 6, 26, 26, 12 }; WORD gwSRC3_REC_FILTER_LENGTH[5] = { 680, 60, 312, 156, 60 }; WORD gwSRC3_REC_FILTER_TAP_SIZE[5] = { 19, 29, 51, 51, 59 }; /* SIZE - 1 */ /* WORD gwSRC3_REC_BIG_LOOP_COUNTER[5] = { 9, 0, 4, 1, -1 }; */ WORD gwSRC3_REC_SMALL_LOOP_COUNTER[5] = { 0, 0, 1, 3, 4 }; WORD gwSRC3_REC_IN_BufferSize[5] = { 37 * 16 * 2, 32 * 6 * 2, 416, 416, 384 }; WORD gwSRC3_REC_OUT_BufferSize[5] = { 160 * 4, 160 * 2, 160 * 2, 160 * 2, 160 * 2 }; #define PB_DMA_BUFFER_SIZE 0x2400 #define PLAYBACK_BUFFER_SIZE PB_DMA_BUFFER_SIZE /*#define WAVE_BUFFER_BLOCK_SIZE (MAXNUM_WAVE_RENDER * PLAYBACK_BUFFER_SIZE) + 0x8000 */ #define STREAM_TYPE_DSPSRC 1 /* high quality SRC stream */ #define STREAM_TYPE_DSPMSRC 2 /* general mini SRC stream */ #define STREAM_TYPE_NULL (( ULONG ) -1 ) BYTE AllocateSRCPlay = FALSE; BYTE AllocateSRCRec = FALSE; /* -------------------------------------------------------------------------- */ /* khs, for full-dupulex */ #define MAX_SRC_STREAMS 2 PHWI gphwi = NULL; #define _Debug_Printf_Service(x) dprintf3((x)) #if 0 extern PHYSICAL_ADDRESS PPhysicalAddress; extern PHYSICAL_ADDRESS RPhysicalAddress; extern ULONG SWTAddress; #endif #define wSPDIFVarLen (CDATA_HEADER_LEN + 10) #define gwSPDIF_IN_BufferSize 192 /* -------------------------------------------------------------------------- */ #define MAXNUM_WAVE_RENDER 1 #define MAXNUM_WAVE_CAPTURE 1 #define MAXNUM_WAVE_MIXER 1 #define MAXNUM_WAVE_CHANNELS MAXNUM_WAVE_RENDER + MAXNUM_WAVE_CAPTURE + MAXNUM_WAVE_MIXER ALLEGRO_WAVE WaveStreams[MAXNUM_WAVE_CHANNELS] = { {0} }; PALLEGRO_WAVE CaptureStream = NULL; PALLEGRO_WAVE PlaybackStream = NULL; PALLEGRO_WAVE MidiStream = NULL; MBUFFER CaptureBuffer; MBUFFER RenderBuffer; MBUFFER MidiBuffer; static int StreamsRunning = 0; void InitStream () { int i; for (i = 0; i < 3; i++) { WaveStreams[i].PositionBeforePaused = 0; WaveStreams[i].DspClientInstance = NULL; WaveStreams[i].StreamType = STREAM_TYPE_NULL; WaveStreams[i].State = KSSTATE_STOP; } WaveStreams[0].WaveType = WAVE_PLAYBACK; WaveStreams[1].WaveType = WAVE_CAPTURE; WaveStreams[2].WaveType = WAVE_MIXER; #if 0 RenderBuffer.Physical = (ULONG) PPhysicalAddress.LowPart; RenderBuffer.Length = 0x2000; WaveStreams[0].Buffer = &RenderBuffer; WaveStreams[0].Length = RenderBuffer.Length; CaptureBuffer.Physical = (ULONG) RPhysicalAddress.LowPart; CaptureBuffer.Length = 0x4000; WaveStreams[1].Buffer = &CaptureBuffer; WaveStreams[1].Length = CaptureBuffer.Length; MidiBuffer.Physical = (ULONG) SWTAddress; MidiBuffer.Length = 3520; WaveStreams[2].Buffer = &MidiBuffer; WaveStreams[2].Length = MidiBuffer.Length; WaveStreams[2].StreamType = STREAM_TYPE_DSPMSRC; #endif PlaybackStream = &WaveStreams[0]; CaptureStream = &WaveStreams[1]; MidiStream = &WaveStreams[2]; } /*ARGSUSED*/ void AllocateStream (allegro_devc * devc, IN BYTE waveType) { dprintf1 (("AllocateStream %d", waveType)); WaveStreams[waveType].DspClientInstance = NULL; WaveStreams[waveType].StreamType = STREAM_TYPE_NULL; WaveStreams[waveType].State = KSSTATE_STOP; /* */ /* at the request of record, turn off SPDIF out if already on. */ /* at the end of record, turn on */ #ifdef later if ((WAVE_CAPTURE == waveType) && fSPDIFOUT) HWMGR_Enable_SPDIF (devc, FALSE); #endif /* SetFormat( &WaveStreams[ waveType ], WaveInfo ); */ } /* AllocateStream */ void FreeStream (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { /* close DSP instance */ dprintf3 (("FreeStream:%x", AllegroWave->DspClientInstance)); if (AllegroWave->DspClientInstance) { if (kCloseInstance (devc, gphwi, AllegroWave->DspClientInstance, KOPENCLOSE_SYNCHRONOUS) != KRETURN_SUCCESS) { /*_Debug_Printf_Service( "Close Inst!\n" ); */ dprintf1 (("ERROR: FreeStream kCloseInstance")); num_errors++; } AllegroWave->DspClientInstance = NULL; } if (IsAC3Format) { /* */ /* reset the spdif out data type to PCM */ HWMGR_WriteDataWord (devc, ASSP_MEMORY_PORT, DSP_DATA_MEMORY); HWMGR_WriteDataWord (devc, ASSP_INDEX_PORT, KDATA_SPDIF_FRAME0); HWMGR_WriteDataWord (devc, ASSP_DATA_PORT, 0x100); } if (STREAM_TYPE_DSPSRC == AllegroWave->StreamType) { AllocateSRCRec = FALSE; AllocateSRCPlay = FALSE; } } /* FreeStream */ void SRCMGR_Stop (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { dprintf1 (("SRCMGR_Stop: Client = %x", AllegroWave->DspClientInstance)); if (AllegroWave->DspClientInstance) { /* stop DMA transfer */ kStopTransfer (devc, gphwi, AllegroWave->DspClientInstance); /* stop the DSP client */ kSetInstanceNotReady (devc, gphwi, AllegroWave->DspClientInstance); } } /* SRCMGR_Stop */ void SRCMGR_StartSPDIFIN (allegro_devc * devc, IN BOOLEAN start) { ULONG FilterLength; ULONG i; USHORT wCC_offset; USHORT wCD_offset; if (start) { if (pClient_SPDIFIN) { kCloseInstance (devc, gphwi, pClient_SPDIFIN, KOPENCLOSE_SYNCHRONOUS); pClient_SPDIFIN = NULL; #if 0 StreamsRunning--; if (0 == StreamsRunning) { WRITE_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL, (USHORT) (READ_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE)); } #endif } kOpenInstance (devc, gphwi, CLIENT_MINISRC, 0, 2 * (MINISRC_TMP_BUFFER_SIZE / 2 + MINISRC_IN_BUFFER_SIZE / 2 + 1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1), &pClient_SPDIFIN); if (pClient_SPDIFIN) { #if 0 StreamsRunning++; if (1 == StreamsRunning) { WRITE_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL, (USHORT) (READ_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL) | CLKRUN_GEN_ENABLE)); } #endif wCC_offset = (WORD) (pClient_SPDIFIN->dwDspCodeClientArea); wCD_offset = (WORD) (pClient_SPDIFIN->dwDspDataClientArea); dprintf1 (("success %x %x %x", pClient_SPDIFIN, wCC_offset, wCD_offset)); kStartTransfer (devc, gphwi, pClient_SPDIFIN, TRUE, 0L, 0L, 0L, 0L, (ULONG) (wCD_offset + MINISRC_TMP_BUFFER_SIZE / 2), (ULONG) (MINISRC_IN_BUFFER_SIZE), (ULONG) (wCD_offset + MINISRC_TMP_BUFFER_SIZE / 2 + MINISRC_IN_BUFFER_SIZE / 2 + 1), (ULONG) (MINISRC_OUT_BUFFER_SIZE), KCONNECT_SPDIFIN, KCONNECT_MIXER); /* ------------------------------------------------------------------------- */ /* load the coefficient starting at offset of program size in program memory */ /* ------------------------------------------------------------------------- */ /* filter length calculation */ FilterLength = sizeof (MINISRC_LPF) / 2; for (i = 0; i < FilterLength; i++) { kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_CODE, wCC_offset + MINISRC_COEF_LOC + i, (USHORT) (MINISRC_LPF[i])); /*since it is in sequence. */ } kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_CODE, wCC_offset + MINISRC_COEF_LOC + FilterLength, 0X8000); /*------------------------------------------------------------------------------------------- */ /* Transfer all parameters into DSP Data memory */ /* All the change below should be consistent with DSP client --- khs 04/17/98 */ /*------------------------------------------------------------------------------------------- */ /* left Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME, 0X7FFF); /* right Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME + 1, 0X7FFF); /* DIRECTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET, 0 /* playback */ ); /* MODE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 1, 0 /* stereo */ ); /* WORDLEN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 2, 0 /* 16bit */ ); /* FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 3, 0X0000); /* FIRST_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 4, 0); /* FIRST_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 5, 0); /* SECOND_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 6, 0); /* SECOND_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 7, 0); /* DELTA_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 8, 0); /* DELTA_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 9, 0); /* ROUND */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 10, 0X8000); /* HIGHER BYTE MASK */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 11, 0XFF00); /* TEMPORARY INPUT BUFFER ADDRESS */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 12, (WORD) (wCD_offset + 40 + 8)); /* TEMP0 */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 13, 0); /* C_FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 14, 0); /* COUNTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 15, 0); /* NUMIN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 16, 8); /* NUMOUT */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 17, 24); /* NUMSTAGE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 18, (MINISRC_BIQUAD_STAGE - 1)); /* COEF */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 19, (WORD) (wCC_offset + MINISRC_COEF_LOC)); /* FILTERTAP */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 20, 0); /* BOOSTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 21, 0); /* SKIPLPF */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 22, 0xFF); /* set the run-flag to start */ kSetInstanceReady (devc, gphwi, pClient_SPDIFIN); } } else { if (pClient_SPDIFIN) { /* stop DMA transfer */ kStopTransfer (devc, gphwi, pClient_SPDIFIN); /* stop the DSP client */ kSetInstanceNotReady (devc, gphwi, pClient_SPDIFIN); kCloseInstance (devc, gphwi, pClient_SPDIFIN, KOPENCLOSE_SYNCHRONOUS); pClient_SPDIFIN = NULL; #if 0 StreamsRunning--; if (0 == StreamsRunning) { WRITE_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL, (USHORT) (READ_PORT_USHORT (devc->osdev, devc->base + HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE)); } #endif } } } /* SRCMGR_StartSPDIFIN */ #define REAL_SHIFT 15 #define REAL_SCALE ( 1 << REAL_SHIFT ) void SRCMGR_SetFrequency (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { LONG frequency; if (AllegroWave->DspClientInstance) { frequency = (AllegroWave->Frequency * REAL_SCALE + 24000) / 48000; if (frequency > 0) --frequency; kSetFrequency (devc, gphwi, AllegroWave->DspClientInstance, (WORD) frequency); } } /* SRCMGR_SetFrequency */ void SRCMGR_StartPlay (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { ULONG FilterLength; ULONG i; ULONG Length; ULONG SizeIn; ULONG SizeOut; ULONG StartOffset; USHORT wCC_offset; USHORT wCD_offset; if (AllegroWave->DspClientInstance) { if (!IsAC3Format) SRCMGR_SetFrequency (devc, AllegroWave); wCC_offset = (WORD) (AllegroWave->DspClientInstance->dwDspCodeClientArea); wCD_offset = (WORD) (AllegroWave->DspClientInstance->dwDspDataClientArea); Length = devc->dma_dac.dmasize; /*AllegroWave->Buffer->Length; */ AllegroWave->Length = Length; if (!IsAC3Format) { StartOffset = 0x20 * 2; SizeIn = MINISRC_IN_BUFFER_SIZE - StartOffset; SizeOut = MINISRC_OUT_BUFFER_SIZE + StartOffset; StartOffset = wCD_offset + MINISRC_TMP_BUFFER_SIZE / 2; kStartTransfer (devc, gphwi, AllegroWave->DspClientInstance, TRUE, devc->dma_dac.base, /*AllegroWave->Buffer->Physical, */ Length, 0L, 0L, StartOffset, SizeIn, StartOffset + SizeIn / 2 + 1, SizeOut, KCONNECT_DMA, KCONNECT_MIXER); /* ------------------------------------------------------------------------- */ /* load the coefficient starting at offset of program size in program memory */ /* ------------------------------------------------------------------------- */ /* filter length calculation */ FilterLength = sizeof (MINISRC_LPF) / 2; for (i = 0; i < FilterLength; i++) { kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_CODE, wCC_offset + MINISRC_COEF_LOC + i, (USHORT) (MINISRC_LPF[i])); /*since it is in sequence. */ } kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_CODE, wCC_offset + MINISRC_COEF_LOC + FilterLength, 0X8000); /*------------------------------------------------------------------------------------------- */ /* Transfer all parameters into DSP Data memory */ /* All the change below should be consistent with DSP client --- khs 04/17/98 */ /*------------------------------------------------------------------------------------------- */ /* left Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME, 0X7FFF); /* right Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME + 1, 0X7FFF); /* DIRECTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET, 0 /* playback */ ); /* MODE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 1, (WORD) ! AllegroWave->FormatStereo); /* WORDLEN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 2, (WORD) ! AllegroWave->Format16Bit); /* FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 3, 0X0000); /* FIRST_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 4, 0); /* FIRST_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 5, 0); /* SECOND_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 6, 0); /* SECOND_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 7, 0); /* DELTA_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 8, 0); /* DELTA_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 9, 0); /* ROUND */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 10, 0X8000); /* HIGHER BYTE MASK */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 11, 0XFF00); /* TEMPORARY INPUT BUFFER ADDRESS */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 12, (WORD) (wCD_offset + 40 + 8)); /* TEMP0 */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 13, 0); /* C_FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 14, 0); /* COUNTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 15, 0); /* NUMIN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 16, 8); if (0 < AllegroWave->Frequency && AllegroWave->Frequency < 8000) { Length = 48000 * 8 / AllegroWave->Frequency; /* add one more for remainder */ ++Length; /* make it even */ if (Length & 1) ++Length; /* NUMOUT */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 17, (USHORT) Length * 2); } else /* NUMOUT */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 17, 50 * 2); /* NUMSTAGE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 18, (MINISRC_BIQUAD_STAGE - 1)); /* COEF */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 19, (WORD) (wCC_offset + MINISRC_COEF_LOC)); /* FILTERTAP */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 20, 0); /* BOOSTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 21, 0); /* SKIPLPF */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 22, (WORD) ((AllegroWave->Frequency > 45000) ? 0xFF : 0)); if (AllegroWave->PositionBeforePaused) kAlterTransfer (devc, gphwi, AllegroWave->DspClientInstance, KALTER_POSITION, TRUE, AllegroWave->PositionBeforePaused); } else { kStartTransfer (devc, gphwi, AllegroWave->DspClientInstance, TRUE, devc->dma_dac.base, /*AllegroWave->Buffer->Physical, */ Length, 0L, 0L, (ULONG) (wCD_offset + wSPDIFVarLen), (ULONG) (gwSPDIF_IN_BufferSize), (DWORD) NULL, 0, KCONNECT_DMA, 0); /* only one parameter */ /* when you close ac3-spdif, you have to put it back with "0x100" */ HWMGR_WriteDataWord (devc, ASSP_MEMORY_PORT, DSP_DATA_MEMORY); HWMGR_WriteDataWord (devc, ASSP_INDEX_PORT, KDATA_SPDIF_FRAME0); HWMGR_WriteDataWord (devc, ASSP_DATA_PORT, 0x102); /*;0x102 -- AC3 data */ } /*;0x100 -- pcm data */ /* set the run-flag to start */ kSetInstanceReady (devc, gphwi, AllegroWave->DspClientInstance); } } /* SRCMGR_StartPlay */ void SRCMGR_StartRecord (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { ULONG Length; ULONG SizeIn; ULONG SizeOut; ULONG StartOffset; USHORT wCD_offset; if (AllegroWave->DspClientInstance) { SRCMGR_SetFrequency (devc, AllegroWave); wCD_offset = (WORD) (AllegroWave->DspClientInstance->dwDspDataClientArea); Length = devc->dma_adc.dmasize; /*AllegroWave->Buffer->Length; */ AllegroWave->Length = Length; StartOffset = 0x10 * 2; SizeIn = MINISRC_IN_BUFFER_SIZE + StartOffset; SizeOut = MINISRC_OUT_BUFFER_SIZE - StartOffset; StartOffset = wCD_offset + MINISRC_TMP_BUFFER_SIZE / 2; kStartTransfer (devc, gphwi, AllegroWave->DspClientInstance, TRUE, 0L, 0L, devc->dma_adc.base, /*AllegroWave->Buffer->Physical, */ Length, StartOffset, SizeIn, StartOffset + SizeIn / 2 + 1, SizeOut, gwDSPConnectIn, KCONNECT_DMA); /*------------------------------------------------------------------------------------------- */ /* Transfer all parameters into DSP Data memory */ /* All the change below should be consistent with DSP client --- khs 04/17/98 */ /*------------------------------------------------------------------------------------------- */ /* left Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME, 0X7FFF); /* right Volume */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + CDATA_LEFT_VOLUME + 1, 0X7FFF); /* DIRECTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET, 1 /* recording */ ); /* MODE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 1, (WORD) ! AllegroWave->FormatStereo); /* WORDLEN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 2, (WORD) ! AllegroWave->Format16Bit); /* FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 3, 0X0000); /* FIRST_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 4, 0); /* FIRST_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 5, 0); /* SECOND_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 6, 0); /* SECOND_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 7, 0); /* DELTA_L */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 8, 0); /* DELTA_R */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 9, 0); /* ROUND */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 10, 0X8000); /* HIGHER BYTE MASK */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 11, 0XFF00); /* TEMPORARY INPUT BUFFER ADDRESS */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 12, (WORD) (wCD_offset + 40 + 8)); /* TEMP0 */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 13, 0); /* C_FRACTION */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 14, 0); /* COUNTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 15, 0); if (0 < AllegroWave->Frequency && AllegroWave->Frequency < 8000) { Length = 48000 * 8 / AllegroWave->Frequency; /* add one more for remainder */ ++Length; /* make it even */ if (Length & 1) ++Length; /* NUMIN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 16, (USHORT) Length); } else /* NUMIN */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 16, 50); /* NUMOUT */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 17, 8); /*AY */ /* NUMSTAGE */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 18, 0); /* COEF */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 19, 0); /* FILTERTAP */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 20, 0); /* BOOSTER */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 21, 0); /* SKIPLPF = FF ; no LPF for any recording */ kDspWriteWord (devc, devc->base, MEMTYPE_INTERNAL_DATA, wCD_offset + SRC3_DIRECTION_OFFSET + 22, 0xFF); /* set the run-flag to start */ kSetInstanceReady (devc, gphwi, AllegroWave->DspClientInstance); } } /* SRCMGR_StartRec */ void SRCMGR_SetVolume (allegro_devc * devc, IN PCLIENT_INST client, IN USHORT left, IN USHORT right) { USHORT lvalue; USHORT rvalue; if (client) { lvalue = left >> 1; rvalue = right >> 1; kSetVolume (devc, gphwi, client, lvalue, rvalue, 0); } } /* SRCMGR_SetVolume */ void SRCMGR_SetRearVolume (allegro_devc * devc, IN PCLIENT_INST client, IN USHORT left, IN USHORT right) { USHORT lvalue; USHORT rvalue; if (client) { lvalue = left >> 1; rvalue = right >> 1; kSetRearVolume (devc, gphwi, client, lvalue, rvalue); } } /* SRCMGR_SetVolume */ void SRCMGR_SetupStream (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { #ifdef SRC4 /* using host src */ AllegroWave->SR_8khzFlag = FALSE; #else /* not using host src */ AllegroWave->SR_8khzFlag = TRUE; #endif if (STREAM_TYPE_NULL == AllegroWave->StreamType) { AllegroWave->StreamType = STREAM_TYPE_DSPSRC; /* 8-bit not supported by SRC */ if (!AllegroWave->Format16Bit) AllegroWave->StreamType = STREAM_TYPE_DSPMSRC; } #if ALLEGRO_DEBUG if (AllegroWave->StreamType == STREAM_TYPE_DSPMSRC) { _Debug_Printf_Service ("M. SRC\r\n"); } else { _Debug_Printf_Service ("SRC 3.X\r\n"); } /* endif */ #endif /* see if we can acquire a DSP client instance for the new */ /* requested format */ if (AllegroWave->StreamType == STREAM_TYPE_DSPSRC) { switch (AllegroWave->Frequency) { case 44100: AllegroWave->wFreqIndex = SRC3_SR_44100; break; case 32000: AllegroWave->wFreqIndex = SRC3_SR_32000; break; #if 1 case 22050: AllegroWave->wFreqIndex = SRC3_SR_22050; break; case 11025: AllegroWave->wFreqIndex = SRC3_SR_11025; break; case 8000: AllegroWave->wFreqIndex = SRC3_SR_8000; /* khs */ AllegroWave->SR_8khzFlag = TRUE; break; #endif default: AllegroWave->StreamType = STREAM_TYPE_DSPMSRC; } } #if 1 AllegroWave->StreamType = STREAM_TYPE_DSPMSRC; /*DON */ dprintf1 (("SRCMGR_SetupStream Mode %d", AllegroWave->StreamType)); #endif #if ALLEGRO_DEBUG if (AllegroWave->StreamType == STREAM_TYPE_DSPMSRC) { _Debug_Printf_Service ("M. SRC\r\n"); } else { _Debug_Printf_Service ("SRC 3.X\r\n"); } /* endif */ #endif /* ok, if it was determined we are to attempt to do a SCR stream */ /* we still don't know if we can so we have to see if the SRC */ /* manager will allow us to do it... and if so we have to try and */ /* get an instance from the DSP kernel, if the SRC manager didn't */ /* let us get it or the DSP kernel didn't allow it we defer it */ /* back to Mini SRC stream */ if (AllegroWave->StreamType == STREAM_TYPE_DSPSRC) { if (WAVE_CAPTURE == AllegroWave->WaveType) { if (!AllocateSRCRec) { /* Temporary Buffer Size: Two Filter Tap buffer, one block of temporary output buffer */ AllegroWave->wSRC3VarLen = SRC3_TEMP_OUTBUF_ADDR_OFFSET + 2 + 2 * (gwSRC3_REC_FILTER_TAP_SIZE[AllegroWave->wFreqIndex] + 1) + 2 + gwSRC3_REC_SIZE_IN[AllegroWave->wFreqIndex] + 1 + gwSRC3_REC_SIZE_OUT[AllegroWave->wFreqIndex] + 1 + 1 + FOR_FUTURE_USE; kOpenInstance (devc, gphwi, CLIENT_SRC, 0, 2 * (AllegroWave->wSRC3VarLen + gwSRC3_REC_IN_BufferSize[AllegroWave-> wFreqIndex] / 2 + 1 + gwSRC3_REC_OUT_BufferSize[AllegroWave-> wFreqIndex] / 2 + 1), &AllegroWave->DspClientInstance); if (AllegroWave->DspClientInstance) { /* SRC does not support full-duplex */ #if 1 AllocateSRCPlay = TRUE; #endif AllocateSRCRec = TRUE; } } } else { if (!AllocateSRCPlay) { /* khs 082098 */ /* Temporary Buffer Size: Two Filter Tap buffer, one block of temporary input/output buffer */ AllegroWave->wSRC3VarLen = SRC3_TEMP_OUTBUF_ADDR_OFFSET + 2 + 2 * (gwSRC3_PB_FILTER_TAP_SIZE[AllegroWave->wFreqIndex] + 1) + 2 + gwSRC3_PB_SIZE_OUT[AllegroWave->wFreqIndex] + 1 + gwSRC3_PB_SIZE_IN[AllegroWave->wFreqIndex] + 1 + FOR_FUTURE_USE; kOpenInstance (devc, gphwi, CLIENT_SRC, 0, 2 * (AllegroWave->wSRC3VarLen + gwSRC3_IN_BufferSize[AllegroWave->wFreqIndex] / 2 + 1 + gwSRC3_OUT_BufferSize[AllegroWave->wFreqIndex] / 2 + 1), /* word */ &AllegroWave->DspClientInstance); dprintf3 (("kOpenIns:%x", AllegroWave->DspClientInstance)); if (AllegroWave->DspClientInstance) { AllocateSRCPlay = TRUE; /* SRC does not support full-duplex */ #if 1 AllocateSRCRec = TRUE; #endif } } } if (!AllegroWave->DspClientInstance) AllegroWave->StreamType = STREAM_TYPE_DSPMSRC; } if (STREAM_TYPE_DSPMSRC == AllegroWave->StreamType) { if (kOpenInstance (devc, gphwi, IsAC3Format ? CLIENT_SPDIF : CLIENT_MINISRC, 0, IsAC3Format ? 2 * (wSPDIFVarLen + gwSPDIF_IN_BufferSize / 2) : 2 * (MINISRC_TMP_BUFFER_SIZE / 2 + MINISRC_IN_BUFFER_SIZE / 2 + 1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1), &AllegroWave->DspClientInstance) != KRETURN_SUCCESS) { dprintf1 (("%x:Open M SRC Inst!\n")); num_errors++; } } } /* SRCMGR_SetupStream */ ULONG SRCMGR_GetPosition (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave) { int i; ULONG Position; ULONG BufferPosition = 0; KIRQL OldIrql; /*dprintf1(("GetPos=%x %x %x %x", AllegroWave->State, AllegroWave->DspClientInstance, AllegroWave->Length, AllegroWave->WaveType)); */ /* to make sure nothing funny happens if this stream is in stop */ /* state, just return 0 */ if (KSSTATE_STOP == AllegroWave->State || !AllegroWave->DspClientInstance) return 0; KeAcquireSpinLock (&gpGDI->ControlSpinLock, &OldIrql); if (WAVE_CAPTURE == AllegroWave->WaveType) { #ifndef DMAREC /* khs 090298 for PIO recording */ kPIOInterruptHandler (devc, gphwi, AllegroWave->DspClientInstance); #endif for (i = 0; i < 100; i++) { if (kQueryPosition (devc, gphwi, AllegroWave->DspClientInstance, FALSE, &BufferPosition) == KRETURN_SUCCESS) break; } #if 0 if (BufferPosition >= AllegroWave->Length) { dprintf1 (("!%d ", BufferPosition)); BufferPosition = 0; } #endif Position = BufferPosition % AllegroWave->Length; } else { for (i = 0; i < 100; i++) { if (kQueryPosition (devc, gphwi, AllegroWave->DspClientInstance, TRUE, &BufferPosition) == KRETURN_SUCCESS) break; } #if 0 if (BufferPosition >= AllegroWave->Length) { dprintf1 (("!%d ", BufferPosition)); BufferPosition = 0; } #endif Position = BufferPosition % AllegroWave->Length; } KeReleaseSpinLock (&gpGDI->ControlSpinLock, OldIrql); return (Position); } /* GetPosition */ void SetFormat (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave, IN PWAVE_INFO WaveInfo) { /* close previous client if it is SRC and sampling rate is different */ if (AllegroWave->DspClientInstance && STREAM_TYPE_DSPSRC == AllegroWave->StreamType && WaveInfo->SamplesPerSec != AllegroWave->Frequency) { dprintf1 (("SetFormat CloseInstance:%x", AllegroWave->DspClientInstance)); if (kCloseInstance (devc, gphwi, AllegroWave->DspClientInstance, KOPENCLOSE_SYNCHRONOUS) != KRETURN_SUCCESS) { _Debug_Printf_Service ("Close inst!\n"); num_errors++; } #if 0 if (WAVE_CAPTURE == AllegroWave->WaveType) AllocateSRCRec = FALSE; else AllocateSRCPlay = FALSE; #else AllocateSRCPlay = FALSE; AllocateSRCRec = FALSE; #endif AllegroWave->DspClientInstance = NULL; AllegroWave->StreamType = STREAM_TYPE_NULL; } AllegroWave->FormatStereo = (WaveInfo->Channels == 2); AllegroWave->Format16Bit = (WaveInfo->BitsPerSample == 16); AllegroWave->Frequency = WaveInfo->SamplesPerSec; dprintf1 (("SetFormat:%d,%d,%d", WaveInfo->SamplesPerSec, WaveInfo->BitsPerSample, WaveInfo->Channels)); } /* SetFormat */ void SetState (allegro_devc * devc, IN PALLEGRO_WAVE AllegroWave, IN KSSTATE NewState) { KIRQL OldIrql; dprintf1 (("SetState=(%x, %x)", AllegroWave->State, NewState)); KeAcquireSpinLock (&gpGDI->ControlSpinLock, &OldIrql); if (AllegroWave->State != NewState) { switch (NewState) { case KSSTATE_STOP: AllegroWave->PositionBeforePaused = 0; if (KSSTATE_RUN == AllegroWave->State) { StreamsRunning--; if (!StreamsRunning) { kSetTimer (devc, gphwi, 0); WRITE_PORT_USHORT (devc->osdev, (devc->base + 0x18), READ_PORT_USHORT (devc->osdev, (devc->base + 0x18)) & ~CLKRUN_GEN_ENABLE); } SRCMGR_Stop (devc, AllegroWave); } break; case KSSTATE_RUN: /* client not opened */ if (!AllegroWave->DspClientInstance) { SRCMGR_SetupStream (devc, AllegroWave); } /* start the transfer on whatevr method specified */ switch (AllegroWave->StreamType) { case STREAM_TYPE_DSPMSRC: if (WAVE_CAPTURE == AllegroWave->WaveType) SRCMGR_StartRecord (devc, AllegroWave); else SRCMGR_StartPlay (devc, AllegroWave); break; } StreamsRunning++; if (1 == StreamsRunning) { /* 4 ms * 12000 / 1000 */ kSetTimer (devc, gphwi, 240); WRITE_PORT_USHORT (devc->osdev, (devc->base + 0x18), READ_PORT_USHORT (devc->osdev, (devc->base + 0x18)) | CLKRUN_GEN_ENABLE); } break; } AllegroWave->State = NewState; } KeReleaseSpinLock (&gpGDI->ControlSpinLock, OldIrql); } /* SetState */ #ifdef later ULONG GetMidiPosition () { return SRCMGR_GetPosition (devc, MidiStream); } PCLIENT_INST pClient; #define DBG_TRACE dprintf1 DWORD InitModem (allegro_devc * devc) { int cnt = 0; int wRC, retry = 0; do { wRC = kOpenInstance (devc, gphwi, CLIENT_MODEM, 0, 512 * 2 + 64, &pClient); /* HSP_Open */ } while ((wRC != KRETURN_SUCCESS) && (cnt++ < 100)); /* enddo */ if (wRC != KRETURN_SUCCESS) { DBG_TRACE (("KOpenInstance from HSP modem fail")); return FALSE; } /* endif */ DBG_TRACE (("KOpenInstance from HSP modem OK")); dprintf1 (("pClient Area=%x", pClient->dwDspDataClientArea)); /* setup the outbuffer address and length so Kernel can */ /* move the output data to MIXER */ retry = 0; do { wRC = kStartTransfer (devc, gphwi, pClient, NULL, NULL, 0, NULL, 0, NULL, 0, pClient->dwDspDataClientArea + 32, 128, KCONNECT_NONE, KCONNECT_MIXER); #if ALLEGRO_DEBUG if (wRC != KRETURN_SUCCESS) { DBG_TRACE (("kStartTransfer fail")); } /* endif */ #endif } while ((wRC != KRETURN_SUCCESS) && (retry++ < 100)); /* enddo */ if (wRC != KRETURN_SUCCESS) { DBG_TRACE (("kStartTransfer fail")); kCloseInstance (gphwi, pClient, 0); #pragma message("----Closing client, can we handle this?") return FALSE; } else { DBG_TRACE (("kStartTransfer OK")); } /* endif */ return TRUE; } VOID CloseModem () { int cnt = 0; int wRC; cnt = 0; if (!pClient) return; do { wRC = kStopTransfer (devc, gphwi, pClient); #if ALLEGRO_DEBUG if (wRC != KRETURN_SUCCESS) { DBG_TRACE (("DSPStopXfer fail")); } /* endif */ #endif } while ((wRC != KRETURN_SUCCESS) && (cnt++ < 100)); cnt = 0; do { wRC = kCloseInstance (devc, gphwi, pClient, 0); } while ((wRC != KRETURN_SUCCESS) && (cnt++ < 100)); /* enddo */ } #endif void SRCMGR_SetPassThruVolume (allegro_devc * devc, IN PPASSTHRU client, IN USHORT left, IN USHORT right) { USHORT lvalue; USHORT rvalue; if (client) { lvalue = left >> 1; rvalue = right >> 1; kSetPassThruVolume (devc, gphwi, client, lvalue, rvalue); dprintf3 (("kSetPassThruVolume %x %x", lvalue, rvalue)); } } /* SRCMGR_SetPassThruVolume */ void SRCMGR_SetPassThruRearVolume (allegro_devc * devc, IN PPASSTHRU client, IN USHORT left, IN USHORT right) { USHORT lvalue; USHORT rvalue; if (!client) return; /*LeftPassThruVolRear = left; */ /*RightPassThruVolRear = right; */ if (client) { lvalue = left >> 1; rvalue = right >> 1; kSetPassThruRearVolume (devc, gphwi, client, lvalue, rvalue); } } /* SRCMGR_SetPassThruRearVolume */