Sound card interrupt problems
My main problem is quite strange. My code does play RAW files and it works perfect, until the file size is larger than my buffer.
In a DOS shell this code works to perfection. In true DOS it does not. The first two blocks play fine, that is the sound card does generate the interrupt once. After the first interrupt when it comes to the end of the next block, the interrupt is not generated.
Since I'm in single cycle DMA, the sound stops. The DMA is not reprogrammed nor is the DSP, the offset is not incremented, and everything hangs. Since I've hooked an interrupt and not unhooked it properly (since the code never comes to the end of the sound) the system is hosed and I must reboot to reset all the chips and to regenerate the interrupt vector table.
[ist][*]Why does the sound card only generate 1 interrupt? If I'm acknowleding all hanging ints and the PIC, it should continue to generate interrupts until the sound is done playing. It only works correctly in a Windows DOS box and I cannot figure out why.
[*]How do you rewrite a Ctrl-C handler? I know you can rewrite these handlers using signal(), but the syntax of the function is so cluttered(and the example code does not work) I cannot figure out how to do it. It is signal(SIGINT,(void)(*near)(int)) or something like that. If I can do this, then on CTRL-C I would uninstall my handler - thus I might not have to reboot every time.[/list]
If I can get this working, then I've finally written an SB16 module that works and can play very long samples. The sample I tested in the Windows DOS box was 800kb in length and it played flawlessly (except for clicking which I know how to fix). Once this works in real-mode, it's on to DJGPP and PM.
Some of this is directly from Ethan Brodsky's code so he deserves the credit
void interrupt newhandler(...)
//Check if sound is done - not the best/safest way to do it
if (done==1) exit(EXIT_SUCCESS);
//Increment offset into file - globals again
//ChunkSize is 32000 bytes
//Load data and get chunk size
//Will be less than 32000 when near the end of the sound file
unsigned int size=LoadData(fileoffset);
//Reprogram the DSP and DMA for next block and start playing
//Acknowledge SB - for 8 bit sound
//Acknowledge pic for int<8
//Acknowledge PIC since caller could be an interrupt handler
//Stop current sound - none should be playing at this point
//Restore the old handler to clean up the vector table
if(handlerinstalled==TRUE) UninstallHandler(); //Clean up
//Reset the DSP for future use
//Close the file
//Disable interrupts (CLI)
//Mask the interrupt
//Save the old handler for later restoration of vector table
oldhandler=getvect(intvector); //intvector is global for now
//Install our handler
//Unmask the interrupt
//Handler is installed
//Re-enable interrupts (STI)
//Disable interrupts (CLI)
//Restore old handler
//Set flag to reflect change
//Enable interrupts (STI)
unsigned int LoadData(unsigned long offset)
//Check for end of sound file
if (offset+32000L>filelength(handle) done=1;
//Get next chunk size
unsigned long size=filelength(handle)-offset;
//if larger than buffer size - clamp to buffer size
if (size>32000L) size=32000;
//read in size bytes
This should be enough code to see what I'm doing. If not, I'll post my whole source later. Again, some variables are global and are not evident or declared in this snippet.