Breaking the vendor kernel is not an option, my concern is not to break
things (especially updates). However, we have guys on the forum writing code
that flashes keyboard LED's to show packets in/out (I'm assuming this writes
directly to a port) (it uses sifled)
So writing direct to the DSP is not possible?
From geocities dot com
/SiliconValley/Park/8933/sound.html , I understand
the following:
The DSP can be from port 0x210 to 0x260. (there's code to find it)
The IRQ number can be found too. (there's code there to find it too)
He states the SB can play direct or DMA. Direct is simple but uses a lot of
processor time, while DMA mode is limited to transferring data only from
lo-ram (first MB). DMA requires a buffer and is limited to 64kb blocks so
the wav samples need to be chopped up. Sound Blaster can issue an IRQ each
time DMA stops.
He sums-up saying that a DMA transfer is:
----------- clip -----------------------
Load the sound data into memory
Set the DSP TIME_CONSTANT to the sampling rate
Set up the DMA chip for the transfer
Write DMA_TYPE_VALUE value to the DSP
Write DATA_LENGTH to the DSP (2 bytes, LSB first) where DATA_LENGTH = number
of bytes to send - 1
Repeat steps 3, 4, 5 to play all the sample
The DSP_TIME_CONSTANT sets the frequency of reproduction, where
(BYTE)TIME_CONSTANT = 256 - 1000000 / frequency
This method allow a sampling rate of max 22222 Hz (Normal Mode). With SB 2.0
or above, we can have a higher frequency, using High Speed mode. The
TIME_COSTANT will be computed in this way:
(WORD)TIME_CONSTANT = 65535 - 256000000 / frequency
The result is a WORD, but we'll send only the MSB to the DSP. The code of
the function to set the sampling rate will be:
// Sets the Time Constant
// 'frequency'(in): the sampling rate
// 'return'(out): result code
PRIVATE BOOL driver_set_time_constant(WORD frequency)
{
if((frequency < driver_capability.min_mono_8) ||
(frequency > driver_capability.max_mono_8)) return(SB_SAMPLE_RATE);
if(frequency > 23 * 1024)
{
WORD time_constant;
time_constant = 65536 - 256000000 / frequency;
sb_dsp_write(SB_TIME_COSTANT);
sb_dsp_write(time_costant >> 8);
driver_use_high_speed = TRUE;
} else {
BYTE time_constant;
time_constant = 256 - 1000000 / frequency;
sb_dsp_write(SB_TIME_COSTANT);
sb_dsp_write(time_costant);
driver_use_high_speed = FALSE;
}
return(SB_OK);
}
We can program the DMA chip in this way (assuming that the Sound Blaster use
DMA channel 1):
Calculate the 20 bit address of the memory buffer you are using where Base
Address = Segment * 16 + Offset
Send the value 05h to port 0Ah (mask off channel 1)
Send the value 00h to port 0Ch (clear the internal DMA flip/flop)
Send the value 49h to port 0Bh (for playback) or 45h to port 0Bh (for
recording)
Write the LSB (bits 0 -> 7) of the 20 bit memory address to port 02h
Write the MSB (bits 8 -> 15) of the 20 bit memory address to ort 02h
Write the Page (bits 16 -> 19) of the 20 bit memory address to port 83h
Send the LSB of DATA_LENGTH to port 03h
Send the MSB of DATA_LENGTH to port 03h
Send the value 01h to port 0Ah (enable channel 1)
---------- end clip --------------
So can it be done? Is there some factiod I'm not catching?
The only thing I can think of is this:
IRQ vectors: When the DMA stops, what to do with it in this kind of kernel.
Since I can't go to that level in Linux I'm curious...
--
View this message in context:
http://www.nabble.com/CLI-wanted---Need-PCM-to-generic-SBout-on-Smoothwall-…
Sent from the linux-audio-dev forum at
Nabble.com.