?? sndplay.c
字號(hào):
/* sndplay.c - Audio file playing demonstration *//* Copyright 2000 Wind River Systems, Inc. *//*modification history--------------------01h,14nov01,jlb Fix fragment size setting (SPR 69972)01g,20dec00,gav Missed change to variable name.01f,20dec00,gav Entry point identical to filename w/o extension.01e,06dec00,jlb Open sound device read/write, fix compile warnings01d,22nov00,gav Added entry point using same form as other examples.01c,14nov00,jlb Changed name of wavplay.c to sndPlay.c and added support for au (Sun) type of audio files01b,11sep00,jlb Use soundcard.h verses sound.h01a,15mar00,jlb written*//*DESCRIPTIONThis file provides a demonstration of the use of the audio devicedriver. An audio file formatted as a wav or an au file is played onthe audio device.This program demonstrates the method to open the audio and mixerdevices and to:\is\i set the volume\i select the number of audio channels\i select the sample rate for the audio stream\i select the size of a sample\ieIn addition this demonstration program may be used with or withoutthe <select> functionality.*//* Includes */#include <vxWorks.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <ioLib.h>#include <unistd.h>#include <string.h>#include <selectLib.h>#include <ugl/ugl.h>#include <ugl/uglos.h>#include <ugl/audio/soundcard.h>#include <ugl/audio/sndWave.h>#include <ugl/audio/sndAu.h>#define AUDIO_DEVICE "/sound/dsp"#define MIXER_DEVICE "/sound/mixer"#define USE_SELECTSTATUS soundPlay (char *);/******************************************************************************* wexSndPlay - start task to play audio file ** This routine spawns a task to play an aduio stream conatined in the file* specified by <filename>.** RETURNS: OK ** ERRNO: N/A*** SEE ALSO: **/int sndPlay ( char *filename /* Name of audio file to play */ ) { uglOSTaskCreate("tWindMLSnd", (UGL_FPTR)soundPlay, 110, 0, 10240, (int)filename, 0,0,0,0); return (OK); }/******************************************************************************* soundPlay - play a sound file ** This routine plays the sound file <filename> on an audio device. The audio* file is read to obtain the header information. The audio stream is checked* to see if the file is formated as a wav or an au file. Using the header* information the audio device is placed in the proper mode and then the* audio stream is sent to the audio device .** RETURNS: OK when the audio file was successfully played; otherwise ERROR** ERRNO: N/A*** SEE ALSO: **/STATUS soundPlay ( char *filename /* Audio file */ ) { unsigned char *buffer; int buffer_size, samplebits, i, blockSize; int size = 0; int fd, sd, md; int channels; int format; UINT32 samplerate, samples, datastart; audio_buf_info info; int maxVol = (100 << 8) | 100;#ifdef USE_SELECT fd_set writeFD;#endif /* USE_SELECT */ /* Initialize WindML */ uglInitialize(); /* Open the audio file */ fd = open (filename, O_RDONLY, 0666); if (fd < 0) { printf ("Error opening file %s\n", filename); return (ERROR); } /* Assume a wav file and read the wav form header file */ if (wavHeaderRead (fd, &channels, &samplerate, &samplebits, &samples, &datastart) == OK) { /* Set the audio format */ if (samplebits == 16) format = AFMT_S16_LE; else format = AFMT_U8; } else /* Error, try to read as an au type file */ auHeaderRead (fd, &channels, &samplerate, &format, &samples, &datastart); /* if format was set, then sound format was recognized */ if (format == -1) { printf ("Sound file format not recognized\n"); close (fd); return (ERROR); } /* Position to the start of the audio data */ if (lseek (fd, datastart, SEEK_SET) != datastart) { printf ("Sound file is corrupted\n"); close (fd); return (ERROR); } /* Open the audio device */ sd = open (AUDIO_DEVICE, O_RDWR, 0666); if (sd < 0) { printf("Unable to open the sound device - %s\n",AUDIO_DEVICE); close (fd); return (ERROR); } /* Open the mixer device */ md = open (MIXER_DEVICE, O_RDWR, 0666); if (md < 0) { printf("Unable to open the mixer device - %s\n",MIXER_DEVICE); close (fd); close (sd); return (ERROR); } /* Print characteristics of the sound data stream */ printf ("File name: %s\n", filename); switch (format) { case AFMT_S16_LE: printf("WAV file - 16 bit signed little endian\n"); size = samples * channels * (samplebits >> 3); break; case AFMT_U8: printf("WAV file - 8 bit unsigned\n"); size = samples * channels * (samplebits >> 3); break; case AFMT_MU_LAW: printf("AU file - 8 bit muLaw\n"); size = samples * channels; samplebits = 8; break; } printf ("Channels: %d\n", channels); printf ("Sample Rate: %d\n", (int)samplerate); printf ("Sample Bits: %d\n", samplebits); printf ("samples: %d\n", (int)samples); /* Although the mixer has default volume settings, lets set the * volume for both channels to max */ ioctl (md, SOUND_MIXER_WRITE_VOLUME, (int)&maxVol); /* Set the device in proper mode for audio form characteristics */ ioctl (sd, SNDCTL_DSP_CHANNELS, (int)&channels); ioctl (sd, SNDCTL_DSP_SPEED, (int)&samplerate); ioctl (sd, SNDCTL_DSP_SETFMT, (int)&format); /* Although the driver has a default fragment size, lets set * to a size of 4k and use 2 fragments. * The argument to this call is an integer encoded as 0xMMMMSSSS * (in hex). The 16 least significant bits determine the * fragment size. The size is 2^SSSS. For example SSSS=0008 gives * fragment size of 256 bytes (2^8). The minimum is 16 bytes (SSSS=4) * and the maximum is total buffer size/2. Some devices or processor * architectures may require larger fragments - in this case the * requested fragment size is automatically increased. */ blockSize = (2 << 16) | 12; ioctl (sd, SNDCTL_DSP_SETFRAGMENT, (int)&blockSize); /* get the maximum data transfer size and allocate buffer. The * size of the buffer to pass to the audio device is such that * each buffer is the maximum that the audio device can handle * without blocking. It is important that the buffer size * be a multiple of the fragment size. */ ioctl (sd, SNDCTL_DSP_GETOSPACE, (int)&info); blockSize = info.fragstotal * info.fragsize; buffer = malloc (blockSize); if (!buffer) { close (fd); return -1; } /* Loop reading audio file and sending to audio device */ while (size > 0) { /* If the audio stream has more than the block size, then * select a read of the block size, otherwise only * read the remaining data from the audio stream. */ buffer_size = size > blockSize ? blockSize : size; /* Read a block of audio data */ i = read (fd, buffer, buffer_size); /* Send audio data to audio device */ write (sd, buffer, buffer_size); /* Optionally use the select processing */#ifdef USE_SELECT /* Pend until write complete */ FD_ZERO (&writeFD); FD_SET (sd, &writeFD); select (FD_SETSIZE, NULL, &writeFD, NULL, NULL);#endif /* USE_SELECT */ /* Update remaining size of audio data */ size -= buffer_size; } /* Close the audio file and the audio device */ free (buffer); close (fd); close (sd); close (md); return (OK); }
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -