home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / audiopdd.zip / waveplay.c < prev    next >
C/C++ Source or Header  |  1999-02-27  |  6KB  |  230 lines

  1. //
  2. // waveplay.c
  3. // 1-Feb-99
  4. //
  5. // USHORT waveplayStart(WAVESTREAM *wsPtr) {
  6. // USHORT waveplayStop(WAVESTREAM *wsPtr) {
  7. // USHORT waveplayEnable(WAVESTREAM *wsPtr) {
  8. // USHORT waveplayInit(USHORT dmaChannel, USHORT flags, USHORT irq) {
  9.  
  10. #include "cs40.h"
  11.  
  12.  
  13. WAVEAUDIO wap;  // ** global **  The heart of it all, hardware-wise
  14.  
  15. // ---------------------------------
  16. // in: wsPtr -> WAVESTREAM structure
  17. //out: 0 if okay, else error
  18. //nts:
  19.  
  20. USHORT waveplayStart(WAVESTREAM *wsPtr) {
  21.  
  22.  USHORT rc = 0;
  23.  UCHAR data;
  24.  STREAM *tstreamPtr = 0; // original typed this as WAVESTREAM*, but FindActiveStream() is STREAM
  25.  USHORT isFD = wsPtr->waPtr->flags & FLAGS_WAVEAUDIO_FULLDUPLEX;
  26.  
  27. #ifdef TRACE_CALIBRATE
  28.  traceCalibrate();
  29. #endif
  30.  
  31. // !!!
  32. //ddprintf("@ waveplayStart, isFD=%u\n",isFD);
  33.  
  34.  // need to know if recording now (only care if full duplex capable)
  35.  
  36.  if (isFD) tstreamPtr = streamFindActive(STREAM_WAVE_CAPTURE);
  37.  
  38.  // whoa! now this is hardware specific -- ensure playback not active, and if not FD, off record
  39.  // this will be moved into a hardware-specific module eventually
  40.  
  41.  data = chipsetGET('i', INTERFACE_CONFIG_REG);
  42.  if (isFD) {
  43.     data = data & 0xFE;  // off PEN
  44.  }
  45.  else {
  46.     data = data & 0xFC;  // off PEN, and CEN since not full duplex
  47.  }
  48.  
  49.  _cli_();
  50.  dmaWaitForChannel(DMA_WAIT, &wsPtr->waPtr->ab);
  51.  chipsetSet('i', INTERFACE_CONFIG_REG, data);
  52.  _sti_();
  53.  
  54.  // mute the dac output
  55.  // MIXER_SOURCE_WAVE is the correct mixer line to send the
  56.  // query and set controls command to...
  57.  // copy the current mute and volume values to temp variables then
  58.  // set the volume to 0 and mute the output
  59.  
  60.  //- pDACOutput->QueryControl(MIX_VOLUME, (ULONG FAR *)&DACVolume);
  61.  //- pDACOutput->SetControl(MIX_MUTE, MUTE_ON);
  62.  //- pDACOutput->SetControl(MIX_VOLUME,0);
  63.  
  64.  chipsetMCE(1); // turn MCE on
  65.  
  66.  // set up interface config reg
  67.  
  68.  if (isFD == 0) {
  69.     data = 0x84;        // playback gets dma capture into pio
  70.  }
  71.  else {
  72.     data = chipsetGET('i', INTERFACE_CONFIG_REG) & (0x18 | 0x02); // preserve CEN (and CAL1,0)
  73.  }
  74.  chipsetSet('i', INTERFACE_CONFIG_REG, data);
  75.  
  76.  // set the Clock and data format reg
  77.  // full-duplex conserns:
  78.  // The 4232 only has 1 clock so the playback and capture sample rates
  79.  // have to be the same. Because of this we have to make some value judgments
  80.  // about how to set up the sampling rate. One could an comeup with many
  81.  // possable rules on how to manage the sampling rate... I have one:
  82.  // THE CAPTURE ALWAYS WINS !!
  83.  // With this in mind we now set up the Fs and Playback Data Format Reg.
  84.  
  85.  if (isFD && tstreamPtr) {
  86.     data = chipsetGET('i', PLAYBACK_DATA_FORMAT_REG) & 15; // preserve the clock config bits..
  87.     data = data | wsPtr->waPtr->formatData;
  88.  }
  89.  else {
  90.     data = wsPtr->waPtr->formatData | wsPtr->waPtr->clockSelectData;
  91.  }
  92.  chipsetSet('i', PLAYBACK_DATA_FORMAT_REG, data);
  93.  
  94.  // wait for the chip to settle down
  95.  
  96.  chipsetWaitInit();
  97.  chipsetMCE(0); // turn MCE off
  98.  
  99.  // Just in case the CAL0 and CAL1 bits are set to anything other than 0b00
  100.  // or if this is the first start since we reset the codec
  101.  // wait for init complete and aci in process to turn off
  102.  
  103.  chipsetWaitInit();
  104.  chipsetWaitACI();
  105.  
  106.  iodelay(WAIT_2MS);
  107.  
  108.  // if this is a dual dma environment (full-duplex) and a
  109.  // capture stream is active, make sure CEN is on.
  110.  
  111.  if (isFD && tstreamPtr) {
  112.     data = chipsetGET('i', INTERFACE_CONFIG_REG) | 2;   // turn on CEN
  113.     chipsetSet('i', INTERFACE_CONFIG_REG, data);
  114.  }
  115.  
  116.  // set the playback base count registers
  117.  
  118.  chipsetSet('i', LOWER_PLAYBACK_COUNT,(UCHAR)wsPtr->waPtr->countData);
  119.  chipsetSet('i', UPPER_PLAYBACK_COUNT,(UCHAR)(wsPtr->waPtr->countData >> 8));
  120.  
  121.  // enable the ISR via DevHelp_SetIRQ
  122.  
  123.  rc = irqEnable(wsPtr->waPtr->irq);
  124.  if (rc) goto ExitNow;
  125.  
  126.  // start up DMA
  127.  
  128.  dmaStart(&wsPtr->waPtr->ab);
  129.  
  130.  // ### unmute the DAC
  131.  //- pDACOutput->SetControl(MIX_MUTE, MUTE_OFF);
  132.  //- pDACOutput->SetControl(MIX_VOLUME,DACVolume);
  133.  
  134.  // why toggle MCE?  Would disrupt and record, see waverec.c for more since it doesn't do this now
  135.  
  136.  chipsetMCE(1); // turn MCE on
  137.  
  138.  data = chipsetGET('i', INTERFACE_CONFIG_REG) | 1; // turn on PEN (enable playback)
  139.  chipsetSet('i', INTERFACE_CONFIG_REG, data);
  140.  
  141.  chipsetMCE(0); // turn MCE off
  142.  
  143. ExitNow:
  144.  return rc;
  145. }
  146.  
  147.  
  148. // ---------------------------------
  149. // in: wsPtr -> WAVESTREAM structure
  150. //out: 0 if okay, else error
  151. //nts:
  152.  
  153. USHORT waveplayStop(WAVESTREAM *wsPtr) {
  154.  
  155.  USHORT rc = 0;
  156.  UCHAR data;
  157.  
  158.  // if PEN is on turn it off
  159.  
  160.  data = chipsetGET('i', INTERFACE_CONFIG_REG);
  161.  
  162. // !!!
  163. //ddprintf("@ waveplayStop, data=%u\n",(USHORT)data);
  164.  
  165.  if (data & 1) {
  166.     data = data & 0xFE;
  167.     _cli_();
  168.     dmaWaitForChannel(DMA_WAIT, &wsPtr->waPtr->ab);
  169.     chipsetSet('i', INTERFACE_CONFIG_REG, data);
  170.     _sti_();
  171.  }
  172.  
  173.  // stop DMA and disable irq (irq gets released only after last disable)
  174.  
  175.  dmaStop(&wsPtr->waPtr->ab);
  176.  rc = irqDisable(wsPtr->waPtr->irq);
  177.  
  178.  chipsetSet('i', ALT_FEATURE_STATUS, CLEAR_PI); // turn int off (do before disabling irq?)
  179.  
  180.  return rc;
  181. }
  182.  
  183.  
  184. // ---------------------------------
  185. // in: wsPtr -> WAVESTREAM structure
  186. //out: 0 if okay, else error
  187. //nts:
  188.  
  189. USHORT waveplayEnable(WAVESTREAM *wsPtr) {
  190.  
  191.  USHORT rc = 0;
  192.  
  193.  return rc;
  194.  wsPtr;
  195. }
  196.  
  197.  
  198. // ------------------
  199. // in: dmaChannel
  200. //     flags:
  201. //      FLAGS_WAVEAUDIO_FULLDUPLEX  1   // can do full-duplex (has separate DMA for play/rec)
  202. //      FLAGS_WAVEAUDIO_DMA16       2   // dma channel is 16-bit
  203. //      FLAGS_WAVEAUDIO_FTYPEDMA    4   // hardware support demand-mode dma
  204. //     irq = number of IRQ (only one...)
  205. //out: 0 if okay, else error
  206. //nts:
  207.  
  208. #pragma code_seg ("_INITTEXT");
  209. #pragma data_seg ("_INITDATA","ENDDS");
  210.  
  211. USHORT waveplayInit(USHORT dmaChannel, USHORT flags, USHORT irq) {
  212.  
  213.  USHORT rc;
  214.  
  215.  MEMSET(&wap,0,sizeof(wap));
  216.  
  217.  wap.devType = AUDIOHW_WAVE_PLAY;
  218.  wap.flags = flags;
  219.  wap.irq = irq;
  220.  
  221.  // waSetup():
  222.  // sets up DMACHANNEL
  223.  // sets up wap.irqHandlerPtr
  224.  
  225.  rc = waSetup(dmaChannel, &wap);
  226.  
  227.  return rc;
  228. }
  229.  
  230.