📄 sbdac.c
字号:
#include <stdio.h>
#include <dos.h>
#include "sb.h"
static void far interrupt (*OldIRQ)();
static volatile int DMA_complete;
static int high_speed = 0;
/* Interrupt handler for DMA complete IRQ from Soundblaster */
static void far interrupt SBHandler()
{
enable();
DMA_complete = 1;
/* Acknowledge the interrupt */
inportb(DSP_DATA_AVAIL);
outportb(0x20,0x20);
}
/* Sets the sample rate to be used for digitising or playback */
unsigned Sb_Sample_Rate(unsigned rate, int direction)
{
unsigned char tc;
tc = (unsigned char) (256 - ((1000000L + rate/2)/rate));
/* Determine the actual sampling rate */
rate = (unsigned) (1000000L / (256 - tc));
/* Do we need to select high-speed mode? */
high_speed = (rate > (direction == PLAY ? MAX_LO_PLAY : MAX_LO_REC));
writedac(TIME_CONSTANT); /* Command byte for sample rate */
writedac(tc); /* Sample rate time constant */
return rate;
}
void Sb_Voice(int state)
{
writedac((state) ? SPEAKER_ON : SPEAKER_OFF);
}
void Sb_Voice_DMA(char far *data, unsigned dlen, int stereo, int direction)
{
unsigned char im, tm;
DMA_complete = 0;
dlen--; /* SB and DMA controller require number of bytes minus 1 */
/* Enable interrupts on PIC */
im = inportb(0x21);
tm = ~(1 << SbIRQ);
outportb(0x21,im & tm);
enable();
/* Setup DMA */
prevent_dma(SbDMAchan);
dma_setup(SbDMAchan,data,dlen,direction);
/* Turn on stereo output */
if(stereo && SbType == SBPro && direction == PLAY)
writemixer(0x0e,0x13);
/* Start the Soundblaster */
if (high_speed) {
writedac(SET_HS_SIZE);
writedac(dlen & 0xff);
writedac(dlen >> 8);
writedac(direction == PLAY ? HS_DAC : HS_ADC);
} else {
writedac(direction == PLAY ? DMA_8_BIT_DAC : DMA_ADC);
writedac(dlen & 0xff);
writedac(dlen >> 8);
}
}
void Sb_Init_Voice_DMA(void interrupt (*handler)(void))
{
/* Insert our IRQ handler into interrupt chain */
disable();
OldIRQ = getvect(0x08 + SbIRQ);
if(!handler)
handler = SBHandler;
setvect(0x08 + SbIRQ,handler);
enable();
}
void Sb_DeInit_Voice_DMA(void)
{
unsigned char tm;
/* Turn off stereo output */
if(SbType == SBPro)
writemixer(0x0e,0x11);
/* Restore old IRQ vector */
disable();
setvect(0x08 + SbIRQ,OldIRQ);
tm = inportb(0x21);
outportb(0x21,tm | (1 << SbIRQ));
enable();
}
int Sb_DMA_Complete(void)
{
return DMA_complete;
}
void Sb_Halt_DMA(void)
{
if (high_speed) {
prevent_dma(SbDMAchan);
} else {
writedac(HALT_DMA);
}
}
void Sb_Continue_DMA(void)
{
if (high_speed) {
allow_dma(SbDMAchan);
} else {
writedac(CONTINUE_DMA);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -