📄 usbaudiodemo.c
字号:
/* usbAudioDemo.c - USB Audio Demo *//* Copyright 1999-2001 Wind River Systems, Inc. *//*Modification history--------------------01b,05mar00,wef Created - adapted from usbTool.*//*DESCRIPTIONThis file demonstrates the use of the USB stack, either the UHCI or OHCI host controller driver, and the USB audio class driver. It is assumed that this source will file be included using the project facility to pull in the INCLUDE_USB_AUDIO_DEMO. In addtion this file assumes the USB stack has alreadybeen initialized and a host controller has been attached. Finally, this demonstration als makes the assumption that the target system has wav files stored on a ATA type device. USB audio Demo instructionsWhen yoru vxWorks image boots, use the demo by entering any of the following commands at the vxWorks prompt:play [file] Plays a wave file. The file name is a file that exists in the current working directory.stop stops song that is currently playingup raises the volume leveldown lowers the volume levelmute brings the volume level to a tolerable leveldisVol shows the current volume levelThis demo works with any of the supported USB speakers listed in the .I "USB Developer's Kit User's Guide"*//* Include files */#include "stdio.h"#include "stdlib.h"#include "string.h"#include "ioLib.h"#include "ctype.h"#include "semLib.h"#include "usrConfig.h"#include "usb/usbPlatform.h" /* Basic definitions */#include "usb/ossLib.h" /* OS abstraction definitions */#include "usb/tools/cmdParser.h" /* Command parser util funcs */#include "usb/tools/wavFormat.h" /* Microsoft .wav file format */#include "usb/usbAudio.h" /* USB audio definitions */#include "drv/usb/usbSpeakerLib.h" /* USB speaker SEQ_DEV driver *//* Defines */#define AUDIO_BFR_SIZE 0x8000#define MAX_NUM_SONGS 14/* Locals */long globalVolume = 0xd000;LOCAL spkrInitialized = FALSE;/*************************************************************************** spkrAttachCallback - receives attach callbacks from speaker SEQ_DEV driver** RETURNS: N/A*/LOCAL SEQ_DEV *pSpkrSeqDev = NULL;LOCAL VOID spkrAttachCallback ( pVOID arg, /* caller-defined argument */ SEQ_DEV *pSeqDev, /* pointer to affected SEQ_DEV */ UINT16 attachCode /* defined as USB_KBD_xxxx */ ) { if (attachCode == USB_SPKR_ATTACH) { if (pSpkrSeqDev == NULL) { if (usbSpeakerSeqDevLock (pSeqDev) != OK) printf ("usbSpeakerSeqDevLock() returned ERROR\n"); else { pSpkrSeqDev = pSeqDev; } } else { printf ("Another channel already in use, ignored.\n"); } } else { if (pSeqDev == pSpkrSeqDev) { if (usbSpeakerSeqDevUnlock (pSeqDev) != OK) printf ("usbSpeakerSeqDevUnlock() returned ERROR\n"); pSpkrSeqDev = NULL; } } }/***************************************************************************** audioThread - Dumps audio data to usbSpeakerLib** By convention, <param> is the file handle for the file to be played and * the global "wavDataLength" should be the length of the data chunk. The* file position should be set to the beginning of the data in the data chunk.** This thread closes the file after reading all data.** RETURNS: N/A*/BOOL audioThreadBusy = FALSE;LOCAL UINT32 wavDataLen;LOCAL BOOL stopFlag = FALSE;VOID audioThread ( pVOID param ) { FILE *wavFile = (FILE *) param; pUINT8 pBfr; UINT32 remDataLen = wavDataLen; UINT32 actLen; stopFlag = FALSE; /* Create a buffer for audio data */ if ((pBfr = malloc (AUDIO_BFR_SIZE)) == NULL) { printf ("Out of memory creating audio buffer.\n"); } else { /* open the audio stream. */ if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, USB_SPKR_IOCTL_OPEN_AUDIO_STREAM, 0) != OK) { printf ("IOCTL OPEN_AUDIO_STREAM returned ERROR.\n"); } else { /* Read audio data and pass it to usbSpeakerLib. */ while ((stopFlag == FALSE) && remDataLen > 0 && (actLen = fread (pBfr, 1, min (remDataLen, AUDIO_BFR_SIZE), wavFile)) > 0) { if ((*pSpkrSeqDev->sd_seqWrt) (pSpkrSeqDev, actLen, pBfr, FALSE) != OK) { printf ("sd_seqWrt() returned ERROR.\n"); break; } else { remDataLen -= actLen; } } /* Mark the end of the audio stream. */ if ((*pSpkrSeqDev->sd_ioctl) (pSpkrSeqDev, USB_SPKR_IOCTL_CLOSE_AUDIO_STREAM, 0) != OK) { printf ("IOCTL CLOSE_AUDIO_STREAM returned ERROR.\n"); } } free (pBfr); } /* Close the input file. */ fclose (wavFile); audioThreadBusy = FALSE; }/*************************************************************************** enterThread - waits for user to press [enter]** RETURNS: N/A*/LOCAL BOOL enterPressed;LOCAL VOID enterThread ( pVOID param ) { FILE *fout = (FILE *) param; char bfr [256]; fprintf (fout, "Press [enter] to terminate polling.\n"); gets (bfr); enterPressed = TRUE;}/*************************************************************************** waitForSpeaker - waits for a speaker to be connected** RETURNS: OK if speaker connected, else ERROR*/STATUS waitForSpeaker (void) { THREAD_HANDLE thread; /* Create thread to watch for keypress */ enterPressed = FALSE; if (OSS_THREAD_CREATE (enterThread, (pVOID) NULL, OSS_PRIORITY_INHERIT, "tEnter", &thread) != OK) { printf ("Error creating tEnter task.\n"); return ERROR; } /* Wait for a speaker to be attached. */ if (pSpkrSeqDev == NULL) { printf ("Waiting for speaker to be attached...\n"); printf ("press enter to stop polling...\n"); while (!enterPressed && pSpkrSeqDev == NULL) OSS_THREAD_SLEEP (1); } /* kill keypress thread */ OSS_THREAD_DESTROY (thread); if (enterPressed) return ERROR; return OK; }/***************************************************************************** parseWavFile - parses and displays info about a .wav file** Attempts to play the .wav file.** NOTE: If this function returns TRUE, the caller SHOULD NOT close the* wavFile. That will be done automatically when playing is finished.* * RETURNS: OK if able to play file, else ERROR.*/LOCAL STATUS parseWavFile ( FILE *wavFile ) { RIFF_HDR riffHdr; char wavSig [RIFF_WAV_DATA_SIG_LEN]; RIFF_CHUNK_HDR chunkHdr; WAV_FORMAT_CHUNK fmtChunk; UINT32 fileLen; UINT32 chunkLen; int i; USB_SPKR_AUDIO_FORMAT fmt; THREAD_HANDLE thread; /* Check the RIFF/WAV header. */ if (fseek (wavFile, 0L, SEEK_SET) != 0) { printf ("Cannot seek to beginning of file.\n"); return ERROR; } if (fread (&riffHdr, 1, sizeof (riffHdr), wavFile) < sizeof (riffHdr) || fread (&wavSig, 1, sizeof (wavSig), wavFile) < sizeof (wavSig)) { printf ("Unexpected end of file reading RIFF header.\n"); return ERROR; } if (memcmp (&riffHdr.signature, RIFF_HDR_SIG, RIFF_HDR_SIG_LEN) != 0 || memcmp (wavSig, RIFF_WAV_DATA_SIG, RIFF_WAV_DATA_SIG_LEN) != 0) { printf ("Not a .wav file.\n"); return ERROR; } /* Read and display known chunks */ fileLen = FROM_LITTLEL (riffHdr.length) + sizeof (riffHdr); /* printf (".wav file size = %lu bytes.\n", (unsigned long) fileLen);*/ while ((UINT32) ftell (wavFile) < fileLen) { /*printf ("\n");*/ /* Read the next chunk header. */ if (fread (&chunkHdr, 1, sizeof (chunkHdr), wavFile) < sizeof (chunkHdr)) { printf ("Unexpected end of file reading chunk header.\n"); return ERROR; } /*printf ("ChunkId = ");*/ for (i = 0; i < RIFF_CHUNK_ID_LEN; i++) /*printf ("%c", chunkHdr.chunkId [i]);*/ /*REMOVE THIS ->*/; chunkLen = FROM_LITTLEL (chunkHdr.length); /*printf ("\nChunkLen = %lu\n", (unsigned long) chunkLen);*/ /* If we recognize the chunkId, then display the chunk. */ if (memcmp (chunkHdr.chunkId, RIFF_WAV_FMT_CHUNK_ID, RIFF_CHUNK_ID_LEN) == 0) { /* Read the format chunk. */ if (fread (&fmtChunk, 1, sizeof (fmtChunk), wavFile) < sizeof (fmtChunk)) { printf ("Unexpected end of file reading format chunk.\n"); return ERROR; } if (fmtChunk.formatTag == WAV_FMT_MS_PCM) /*printf ("bitsPerSample = %d\n", FROM_LITTLEW (fmtChunk.fmt.msPcm.bitsPerSample));*/ ; /* Attempt to set the audio format to match */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -