usrUsbAudioDemo.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usrUsbAudioDemo.c - USB Audio Demo */
  2. /* Copyright 1999-2002 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01b,08dec01,wef fixed some warnings
  7. 01a,05mar00,wef Created - adapted from usbTool.
  8. */
  9. /*
  10. DESCRIPTION
  11. This file demonstrates the use of the USB stack, either the UHCI or OHCI host 
  12. controller driver, and the USB audio class driver.  It is assumed that this 
  13. source will file be included using the project facility to pull in the 
  14. INCLUDE_USB_AUDIO_DEMO. In addtion this file assumes the USB stack has already
  15. been initialized and a host controller has been attached.  Finally, this 
  16. demonstration als makes the assumption that the target system has wav files 
  17. stored on a ATA type device.  
  18. USB audio Demo instructions
  19. When yoru vxWorks image boots, use the demo by entering any of the following 
  20. commands at the vxWorks prompt:
  21. play [file]  Plays a wave file.  The file name is a file that exists in the
  22. current working directory.
  23. stop stops song that is currently playing
  24. up raises the volume level
  25. down lowers the volume level
  26. mute brings the volume level to a tolerable level
  27. disVol shows the current volume level
  28. This demo works with any of the supported USB speakers listed in the 
  29. .I "USB Developer's Kit User's Guide"
  30. */
  31. /* Include files */
  32. #include "stdio.h"
  33. #include "stdlib.h"
  34. #include "string.h"
  35. #include "ioLib.h"
  36. #include "ctype.h"
  37. #include "semLib.h"
  38. #include "usrConfig.h"
  39. #include "usb/usbPlatform.h" /* Basic definitions */
  40. #include "usb/ossLib.h" /* OS abstraction definitions */
  41. #include "usb/tools/cmdParser.h" /* Command parser util funcs */
  42. #include "usb/tools/wavFormat.h" /* Microsoft .wav file format */
  43. #include "usb/usbAudio.h" /* USB audio definitions */
  44. #include "drv/usb/usbSpeakerLib.h" /* USB speaker SEQ_DEV driver */
  45. /* Defines */
  46. #define AUDIO_BFR_SIZE 0x8000
  47. #define MAX_NUM_SONGS 14
  48. /* Locals */
  49. long globalVolume = 0xd000;
  50. LOCAL BOOL spkrInitialized = FALSE;
  51. /*************************************************************************
  52. *
  53. * spkrAttachCallback - receives attach callbacks from speaker SEQ_DEV driver
  54. *
  55. * RETURNS: N/A
  56. */
  57. LOCAL SEQ_DEV *pSpkrSeqDev = NULL;
  58. LOCAL VOID spkrAttachCallback
  59. (
  60. pVOID arg, /* caller-defined argument */
  61. SEQ_DEV *pSeqDev, /* pointer to affected SEQ_DEV */
  62. UINT16 attachCode /* defined as USB_KBD_xxxx */
  63. )
  64.     {
  65.     if (attachCode == USB_SPKR_ATTACH)
  66. {
  67. if (pSpkrSeqDev == NULL)
  68.     {
  69.     if (usbSpeakerSeqDevLock (pSeqDev) != OK)
  70. printf ("usbSpeakerSeqDevLock() returned ERRORn");
  71.     else
  72. {
  73. pSpkrSeqDev = pSeqDev;
  74. }
  75.     }
  76. else
  77.     {
  78.     printf ("Another channel already in use, ignored.n");
  79.     }
  80. }
  81.     else
  82. {
  83. if (pSeqDev == pSpkrSeqDev)
  84.     {
  85.     if (usbSpeakerSeqDevUnlock (pSeqDev) != OK)
  86. printf ("usbSpeakerSeqDevUnlock() returned ERRORn");
  87.     pSpkrSeqDev = NULL;
  88.     }
  89. }
  90.     }
  91. /***************************************************************************
  92. *
  93. * audioThread - Dumps audio data to usbSpeakerLib
  94. *
  95. * By convention, <param> is the file handle for the file to be played and 
  96. * the global "wavDataLength" should be the length of the data chunk.  The
  97. * file position should be set to the beginning of the data in the data chunk.
  98. *
  99. * This thread closes the file after reading all data.
  100. *
  101. * RETURNS: N/A
  102. */
  103. BOOL audioThreadBusy = FALSE;
  104. LOCAL UINT32 wavDataLen;
  105. LOCAL    BOOL stopFlag = FALSE;
  106. VOID audioThread
  107. (
  108. pVOID param
  109. )
  110.     {
  111.     FILE *wavFile = (FILE *) param;
  112.     pUINT8 pBfr;
  113.     UINT32 remDataLen = wavDataLen;
  114.     UINT32 actLen;
  115.     stopFlag = FALSE;
  116.     /* Create a buffer for audio data */
  117.     if ((pBfr = malloc (AUDIO_BFR_SIZE)) == NULL)
  118. {
  119. printf ("Out of memory creating audio buffer.n");
  120. }
  121.     else
  122. {
  123. /* open the audio stream. */
  124. if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, 
  125.       USB_SPKR_IOCTL_OPEN_AUDIO_STREAM, 0) != OK)
  126.     {
  127.     printf ("IOCTL OPEN_AUDIO_STREAM returned ERROR.n");
  128.     }
  129. else
  130.     {
  131.     /* Read audio data and pass it to usbSpeakerLib. */
  132.     while ((stopFlag == FALSE) && remDataLen > 0 &&
  133.     (actLen = fread (pBfr, 
  134.      1, 
  135.      min (remDataLen, AUDIO_BFR_SIZE), 
  136.      wavFile)) > 0)
  137. {
  138. if ((*pSpkrSeqDev->sd_seqWrt) (pSpkrSeqDev, 
  139.        actLen,
  140.        pBfr, 
  141.        FALSE) 
  142.      != OK)
  143.     {
  144.     printf ("sd_seqWrt() returned ERROR.n");
  145.     break;
  146.     }
  147. else
  148.     {
  149.     remDataLen -= actLen;
  150.     }
  151. }
  152.     /* Mark the end of the audio stream. */
  153.     if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, 
  154.     USB_SPKR_IOCTL_CLOSE_AUDIO_STREAM, 0) != OK)
  155. {
  156. printf ("IOCTL CLOSE_AUDIO_STREAM returned ERROR.n");
  157. }
  158.     }
  159. free (pBfr);
  160. }
  161.     /* Close the input file. */
  162.     fclose (wavFile);
  163.     audioThreadBusy = FALSE;
  164.     }
  165. /*************************************************************************
  166. *
  167. * enterThread - waits for user to press [enter]
  168. *
  169. * RETURNS: N/A
  170. */
  171. LOCAL BOOL enterPressed;
  172. LOCAL VOID enterThread
  173. (
  174. pVOID param
  175. )
  176.     {
  177.     FILE *fout = (FILE *) param;
  178.     char bfr [256];
  179.     fprintf (fout, "Press [enter] to terminate polling.n");
  180.     gets (bfr);
  181.     enterPressed = TRUE;
  182. }
  183. /*************************************************************************
  184. *
  185. * waitForSpeaker - waits for a speaker to be connected
  186. *
  187. * RETURNS: OK if speaker connected, else ERROR
  188. */
  189. STATUS waitForSpeaker (void)
  190.     {
  191.     THREAD_HANDLE thread;
  192.     /* Create thread to watch for keypress */
  193.     enterPressed = FALSE;
  194.     if (OSS_THREAD_CREATE (enterThread, 
  195.    (pVOID) NULL, 
  196.    OSS_PRIORITY_INHERIT, 
  197.    "tEnter",
  198.    &thread) 
  199.  != OK)
  200. {
  201. printf ("Error creating tEnter task.n");
  202. return ERROR;
  203. }
  204.     /* Wait for a speaker to be attached. */
  205.     if (pSpkrSeqDev == NULL)
  206. {
  207. printf ("Waiting for speaker to be attached...n");
  208. printf ("press enter to stop polling...n");
  209. while (!enterPressed && pSpkrSeqDev == NULL)
  210. OSS_THREAD_SLEEP (1);
  211. }
  212.     /* kill keypress thread */
  213.     OSS_THREAD_DESTROY (thread);
  214.     if (enterPressed)
  215. return ERROR;
  216.     return OK;
  217.     }
  218. /***************************************************************************
  219. *
  220. * parseWavFile - parses and displays info about a .wav file
  221. *
  222. * Attempts to play the .wav file.
  223. *
  224. * NOTE: If this function returns TRUE, the caller SHOULD NOT close the
  225. * wavFile.  That will be done automatically when playing is finished.
  226. * RETURNS: OK if able to play file, else ERROR.
  227. */
  228. LOCAL STATUS parseWavFile 
  229. (
  230. FILE *wavFile
  231. )
  232.     {
  233.     RIFF_HDR riffHdr;
  234.     char wavSig [RIFF_WAV_DATA_SIG_LEN];
  235.     RIFF_CHUNK_HDR chunkHdr;
  236.     WAV_FORMAT_CHUNK fmtChunk;
  237.     UINT32 fileLen;
  238.     UINT32 chunkLen;
  239.     int i;
  240.     USB_SPKR_AUDIO_FORMAT fmt;
  241.     THREAD_HANDLE thread;
  242.     /* Check the RIFF/WAV header. */
  243.     if (fseek (wavFile, 0L, SEEK_SET) != 0) 
  244. {
  245. printf ("Cannot seek to beginning of file.n");
  246. return ERROR;
  247. }
  248.     if (fread (&riffHdr, 1, sizeof (riffHdr), wavFile) < sizeof (riffHdr) ||
  249. fread (&wavSig, 1, sizeof (wavSig), wavFile) < sizeof (wavSig)) 
  250. {
  251. printf ("Unexpected end of file reading RIFF header.n");
  252. return ERROR;
  253. }
  254.     if (memcmp (&riffHdr.signature, RIFF_HDR_SIG, RIFF_HDR_SIG_LEN) != 0 ||
  255. memcmp (wavSig, RIFF_WAV_DATA_SIG, RIFF_WAV_DATA_SIG_LEN) != 0) 
  256. {
  257. printf ("Not a .wav file.n");
  258. return ERROR;
  259. }
  260.     /* Read and display known chunks */
  261.     fileLen = FROM_LITTLEL (riffHdr.length) + sizeof (riffHdr);
  262.     /*  printf (".wav file size = %lu bytes.n", (unsigned long) fileLen);*/
  263.     while ((UINT32) ftell (wavFile) < fileLen)
  264. {
  265. /*printf ("n");*/
  266. /* Read the next chunk header. */
  267. if (fread (&chunkHdr, 1, sizeof (chunkHdr), wavFile) < sizeof (chunkHdr))
  268.     {
  269.     printf ("Unexpected end of file reading chunk header.n");
  270.     return ERROR;
  271.     }
  272. /*printf ("ChunkId = ");*/
  273. for (i = 0; i < RIFF_CHUNK_ID_LEN; i++)
  274. /*printf ("%c", chunkHdr.chunkId [i]);*/ /*REMOVE THIS ->*/;
  275. chunkLen = FROM_LITTLEL (chunkHdr.length);
  276. /*printf ("nChunkLen = %lun", (unsigned long) chunkLen);*/
  277. /* If we recognize the chunkId, then display the chunk. */
  278. if (memcmp (chunkHdr.chunkId, RIFF_WAV_FMT_CHUNK_ID, RIFF_CHUNK_ID_LEN) == 0)
  279.     {
  280.     /* Read the format chunk. */
  281.     if (fread (&fmtChunk, 1, sizeof (fmtChunk), wavFile) < sizeof (fmtChunk))
  282. {
  283. printf ("Unexpected end of file reading format chunk.n");
  284. return ERROR;
  285. }
  286.     if (fmtChunk.formatTag == WAV_FMT_MS_PCM)
  287.     /*printf ("bitsPerSample = %dn", 
  288.     FROM_LITTLEW (fmtChunk.fmt.msPcm.bitsPerSample));*/ ;
  289.     /* Attempt to set the audio format to match */
  290.     if (FROM_LITTLEW (fmtChunk.formatTag) == WAV_FMT_MS_PCM)
  291. {
  292. memset (&fmt, 0, sizeof (fmt));
  293. fmt.formatTag = USB_AUDIO_TYPE1_PCM;
  294. fmt.formatType = USB_AUDIO_FORMAT_TYPE1;
  295. fmt.channels = FROM_LITTLEW (fmtChunk.channels);
  296. fmt.subFrameSize = FROM_LITTLEW (fmtChunk.blockAlign) / 
  297. FROM_LITTLEW (fmtChunk.channels);
  298. fmt.bitRes = FROM_LITTLEW (fmtChunk.fmt.msPcm.bitsPerSample);
  299. fmt.sampleFrequency = FROM_LITTLEL (fmtChunk.samplesPerSec);
  300. if (pSpkrSeqDev->sd_ioctl (pSpkrSeqDev, 
  301.    USB_SPKR_IOCTL_SET_AUDIO_FORMAT, 
  302.    (int) &fmt) 
  303.  == OK)
  304.     {
  305.     printf ("nusbSpeakerLib format set successfully.n");
  306.     }
  307. else
  308.     {
  309.     printf ("nFailed to set usbSpeakerLib format.n");
  310.     return ERROR;
  311.     }
  312. }
  313.     }
  314. else if (memcmp (chunkHdr.chunkId, RIFF_WAV_DATA_CHUNK_SIG, RIFF_CHUNK_ID_LEN) == 0)
  315.     {
  316.     /* data chunk found */
  317.     /* launch thread to dump audio data. */
  318.     wavDataLen = FROM_LITTLEL (chunkHdr.length);
  319.     if (OSS_THREAD_CREATE (audioThread, 
  320.    (pVOID) wavFile, 
  321.    OSS_PRIORITY_INHERIT, 
  322.    "tPlay", 
  323.    &thread) 
  324.  != OK)
  325. {
  326. printf ("Cannot create audio play thread.n");
  327. return ERROR;
  328. }
  329.     else
  330. {
  331. audioThreadBusy = TRUE;
  332. return OK;
  333. }
  334.     }
  335. else
  336.     {
  337.     /* Skip over the chunk. */
  338.     fseek (wavFile, chunkLen, SEEK_CUR);
  339.     }
  340. }
  341.     return ERROR;
  342.     }
  343. /*************************************************************************
  344. *
  345. * play - sends a .wav file to a speaker
  346. *
  347. * RETURNS:  OK or ERROR
  348. */
  349. STATUS play (char * fileName)
  350.     {
  351.     FILE *f;
  352.     /* Make sure usbSpeakerLib is initialized and a speaker is available */
  353.     if (!spkrInitialized)
  354. {
  355. printf ("USB speaker SEQ_DEV driver not initialized.n");
  356. return ERROR;
  357. }
  358.     if (audioThreadBusy)
  359. {
  360. printf ("audioThread is busy.n");
  361. return ERROR;
  362. }
  363.     if (waitForSpeaker () != OK)
  364. return ERROR;
  365.     /* Attempt to open the file. */
  366.     if ((f = fopen (fileName, "rb")) == NULL) 
  367. {
  368. printf ("Unable to open '%s'.n", fileName);
  369. return ERROR;
  370. }
  371.     /* Parse the file */
  372.     if (parseWavFile (f) != OK)
  373. fclose (f);
  374.     return OK;
  375.     }
  376. /*************************************************************************
  377. *
  378. * stop - halts the playing of a wav
  379. *
  380. * RETURNS:  OK or ERROR
  381. */
  382. STATUS stop (void)
  383.     {
  384.     /* Make sure usbSpeakerLib is initialized and a speaker is available */
  385.     if (!spkrInitialized)
  386. {
  387. printf ("USB speaker SEQ_DEV driver not initialized.n");
  388. return ERROR;
  389. }
  390.     if (!audioThreadBusy)
  391. {
  392. printf ("No audio is being played.n");
  393. return ERROR;
  394. }
  395.     stopFlag = TRUE;
  396.     return OK;
  397.     }
  398. /*************************************************************************
  399. *
  400. * vol - displays or sets speaker volume
  401. *
  402. * RETURNS:  OK or ERROR
  403. */
  404. LOCAL STATUS vol
  405.     (
  406.     long volume /* Generic parameter passed down */
  407.     )
  408.     {
  409.     short volSetting;
  410.     UINT16 channels;
  411.     pUSB_SPKR_CHANNEL_CAPS pCaps;
  412.     UINT16 i;
  413.     /* verify a speaker is available */
  414.     if (!spkrInitialized)
  415. {
  416. printf ("USB speaker SEQ_DEV driver not initialized.n");
  417. return ERROR;
  418. }
  419.     if (waitForSpeaker () != OK)
  420. return ERROR;
  421.     /* Try to get channel information. */
  422.     if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, 
  423.   USB_SPKR_IOCTL_GET_CHANNEL_COUNT, 
  424.   (int) 
  425.   &channels) 
  426. != OK)
  427. {
  428. printf ("IOCTL GET_CHANNEL_COUNT returned ERROR.n");
  429. return ERROR;
  430. }
  431.     if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, 
  432.   USB_SPKR_IOCTL_GET_CHANNEL_CAPS, 
  433.   (int) 
  434.   &pCaps) 
  435. != OK)
  436. {
  437. printf ("IOCTL GET_CHANNEL_CAPS returned ERROR.n");
  438. return ERROR;
  439. }
  440.     /* Get volume parameter (if specified). */
  441.     /* If volume specified, then set it, else display current volume info */
  442.     for (i = 0; i <= channels; i++)
  443. {
  444. printf ("Channel %d: ", i);
  445. if (!pCaps [i].volume.supported)
  446.     {
  447.     printf ("Volume not supported.n");
  448.     }
  449. else
  450.     {
  451.     if (volume != -1)
  452. {
  453. /* Set volume */
  454. globalVolume = (long) volSetting = (short) (volume & 0xffff);
  455. if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, 
  456.       USB_SPKR_IOCTL_SET_VOLUME, 
  457.       (int) ((i << 16) | ((UINT16) volSetting))) 
  458.    == OK)
  459.     {
  460.     printf ("Volume set to %hx.n", volSetting);
  461.     }
  462. else
  463.     {
  464.     printf ("Error setting volume.n");
  465.     }
  466. }
  467.     else
  468. {
  469. /* Show volume settings. */
  470. printf ("res = %hx, min = %hx, max = %hx, cur = %hx.n",
  471. pCaps [i].volume.res, pCaps [i].volume.min, 
  472. pCaps [i].volume.max, pCaps [i].volume.cur);
  473. }
  474.     }
  475. }
  476.     return OK;
  477.     }
  478. /*************************************************************************
  479. *
  480. * disVol - displays volume levels in hex
  481. *
  482. * RETURNS:  OK or ERROR
  483. */
  484. STATUS disVol (void)
  485.     {
  486.     return (vol(-1));
  487.     }
  488. /*************************************************************************
  489. *
  490. * up - increases the volume
  491. *
  492. * RETURNS:  OK or ERROR
  493. */
  494. STATUS up (void)
  495.     {
  496.     return (vol(globalVolume + 0x200));
  497.     }
  498. /*************************************************************************
  499. *
  500. * down - increases the volume
  501. *
  502. * RETURNS:  OK or ERROR
  503. */
  504. STATUS down (void)
  505.     {
  506.  
  507.     
  508.     return (vol(globalVolume - 0x200));
  509.     }
  510. /*************************************************************************
  511. *
  512. * down - increases the volume
  513. *
  514. * RETURNS:  OK or ERROR
  515. */
  516. STATUS mute (void)
  517.     {
  518.     return (vol(0xd000));
  519.     }
  520. /*************************************************************************
  521. *
  522. * usbSpkrInit - initializes USB speaker SEQ_DEV driver
  523. *
  524. * RETURNS: ERROR or OK
  525. */
  526. UINT16 usbSpkrInit()
  527.     {
  528.     if (spkrInitialized)
  529. {
  530. printf ("USB speaker SEQ_DEV driver already initialized.n");
  531. return ERROR;
  532. }
  533.     /*  Initialize the speaker driver */
  534.     if (usbSpeakerDevInit () == OK)
  535. {
  536. printf ("usbSpeakerDevInit() returned OKn");
  537. spkrInitialized = TRUE;
  538. /* Register for attach notification */
  539. if (usbSpeakerDynamicAttachRegister ((USB_SPKR_ATTACH_CALLBACK)spkrAttachCallback, 
  540.      (pVOID)NULL) != OK)
  541.     {
  542.     printf ("usbSpeakerDynamicAttachRegister() returned ERRORn");
  543.     return OK;
  544.     }
  545. }
  546.     else
  547. printf ("usbSpeakerDevInit() returned ERRORn");
  548.     audioThreadBusy = FALSE;
  549.     return OK;
  550.     }
  551. /*************************************************************************
  552. *
  553. * usrUsbAudioDemo - Entry point to USB audio demo
  554. *
  555. * RETURNS:  OK or ERROR
  556. */
  557. extern STATUS usrUsbAudioDemo (void)
  558.     {
  559.     char * directoryName;
  560.     
  561.     
  562.     /* Initialize the speaker class driver */
  563.     
  564.     usbSpkrInit();
  565.     directoryName = "/ata0";
  566.     /* Initialize the storage device */
  567.     if (usrAtaConfig(0, 0, directoryName) != OK)
  568. {
  569. printf ("ATA configuration failed.n");
  570. return ERROR;
  571. }
  572.     
  573.     return OK;
  574.     }