Linux-based open-source wavplay player

Source: Internet
Author: User

**************************************** **************************************** **************************************** ***
Author: EasyWave time: 2013.02.05

Category: wavplay player Declaration for Linux applications: reprinted. Please keep the link

NOTE: If any error occurs, please correct it. These are my Learning Log articles ......

**************************************** **************************************** **************************************** ***

Because the customer needs to use wav files to test and play our platform, and the customer's applications are used on our platform, there will be some problems, so, I need to find an open source wav player on the network and finally find the wavplay player on the network. although it is a wav Player Based on the OSS architecture, it does not matter. You should first familiarize yourself with this open-source code. The latest version is 2.0. The source code is as follows:

Http://sourceforge.net/projects/wavplay? Source = dlp take a moment to transplant it to the ARM platform after the festival. This software is used for testing or porting to actual projects. For us, is a good reference source code. Do you mean no?

I. wav file format[Network referenced, modified]

As one of the acoustic file formats used in multimedia, the wave file is in the RIFF format as the standard. RIFF is short for Resource Interchange File Format. The first four bytes of each WAVE File are "RIFF", and the WAVE File is composed of several chunks. The location where the file appears includes riff wave Chunk, Format Chunk, Fact Chunk (optional), and Data Chunk. As shown in:

 

Three other chunks except Fact Chunk are required. Each Chunk has its own ID, which is located at the very beginning of the Chunk and serves as an identifier. Each Chunk contains 4 bytes. In addition, the Chunk Size follows the ID (the remaining number of other bytes after removing the number of bytes occupied by ID and Size), 4 bytes, and low bytes indicate the low value, high byte indicates a high value. The following describes the content of each Chunk.Note: All values indicate low bytes, and high bytes indicate high.

1): riff wave Chunk

Use '0000f' as the marker, followed by the size field. The size is the Size of the whole wav file minus the number of bytes occupied by ID and Size, that is, FileLen-8 = size. Then the Type field, which is 'wave ', indicates a wav file.

2): Format Chunk

Use 'fmt' as the flag. Generally, the Size is 16, and no additional information is added at the end. If the value is 18, two additional bytes are added at the end. The wav format made mainly by some software contains the additional information of the two bytes.

3): Fact Chunk

Fact Chunk is an optional field. Generally, when a wav file is converted from some software, it contains the Chunk.

4): Data Chunk

The Data Chunk is the place where the wav data is actually stored. 'data' is used as the Chunk identifier. Then the data size. Followed by wav data. Based on the number of channels in the Format Chunk and the number of sampled bits, the bit location of wav data can be divided into the following forms:

Ii. wav File Format Decoding

For specific code, you can carefully study the wavfile. c and wavfile. H files in the source code of wavplay. These two files mainly decode the wav file format. The specific code is as follows:

/* $Id: wavfile.c,v 1.3 2009/11/30 15:02:31 ve3wwg Exp $ * Copyright: wavfile.c (c) Erik de Castro Lopo  erikd@zip.com.au * * wavfile.c - Functions for reading and writing MS-Windoze .WAV files. * * This  program is free software; you can redistribute it and/or modify it * under the  terms  of  the GNU General Public License as published by the * Free Software Foundation. *  * This  program  is  distributed  in  the hope that it will be useful, but * WITHOUT   ANY   WARRANTY;   without   even  the   implied   warranty  of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details (licensed by file COPYING or GPLv*). *  * This code was originally written to manipulate Windoze .WAV files * under i386 Linux (erikd@zip.com.au). * * ve3wwg@gmail.com */static const char rcsid[] = "$Id: wavfile.c,v 1.3 2009/11/30 15:02:31 ve3wwg Exp $";#include  <stdio.h>#include<errno.h>#include<sys/types.h>#include<unistd.h>#include  <string.h>#include "wavplay.h"#defineBUFFERSIZE   1024#definePCM_WAVE_FORMAT   1#defineTRUE1#defineFALSE0typedef  struct{u_long     dwSize ;u_short    wFormatTag ;u_short    wChannels ;u_long     dwSamplesPerSec ;u_long     dwAvgBytesPerSec ;u_short    wBlockAlign ;u_short    wBitsPerSample ;} WAVEFORMAT ;typedef  struct{char    RiffID [4] ;u_long    RiffSize ;char    WaveID [4] ;char    FmtID  [4] ;u_long    FmtSize ;u_short   wFormatTag ;u_short   nChannels ;u_longnSamplesPerSec ;u_longnAvgBytesPerSec ;u_shortnBlockAlign ;u_shortwBitsPerSample ;charDataID [4] ;u_longnDataBytes ;} WAVE_HEADER ;/*=================================================================================================*/char*  findchunk (char* s1, char* s2, size_t n) ;/*=================================================================================================*/static  WAVE_HEADER  waveheader ={{ 'R', 'I', 'F', 'F' },0,{ 'W', 'A', 'V', 'E' },{ 'f', 'm', 't', ' ' },16,/* FmtSize*/PCM_WAVE_FORMAT,/* wFormatTag*/0,/* nChannels*/0,0,0,0,{ 'd', 'a', 't', 'a' },0} ; /* waveheader*/static ErrFunc v_erf;/* wwg: Error reporting function *//* * Error reporting function for this source module: */static voiderr(const char *format,...) {va_list ap;if ( v_erf == NULL )return;/* Only report error if we have function */va_start(ap,format);v_erf(format,ap);/* Use caller's supplied function */va_end(ap);}int  WaveWriteHeader (int wavefile, int channels, u_long samplerate, int sampbits, u_long samples, ErrFunc erf){ u_longdatabytes ;u_shortblockalign ;v_erf = erf;/* wwg: Set error reporting function */if ( wavefile < 0 ) {err("Invalid file descriptor");return WW_BADOUTPUTFILE ;}sampbits   = (sampbits == 16) ? 16 : 8 ;blockalign = ((sampbits == 16) ? 2 : 1) * channels ;databytes  = samples * (u_long) blockalign ;waveheader.RiffSize    = sizeof (WAVE_HEADER) + databytes - 8 ;waveheader.wFormatTag      = PCM_WAVE_FORMAT ;waveheader.nChannels       = channels ;waveheader.nSamplesPerSec  = samplerate ;waveheader.nAvgBytesPerSec = samplerate * (u_long) blockalign ;waveheader.nBlockAlign     = blockalign ;waveheader.wBitsPerSample  = sampbits ;waveheader.nDataBytes      = databytes;if (write (wavefile, &waveheader, sizeof (WAVE_HEADER)) != sizeof (WAVE_HEADER)) {err("%s",strerror(errno));/* wwg: report the error */return  WW_BADWRITEHEADER ;}  return 0 ;} ; /* WaveWriteHeader*/int  WaveReadHeader  (int wavefile, int* channels, u_long* samplerate, int* samplebits, u_long* samples, u_long* datastart,ErrFunc erf){static  WAVEFORMAT  waveformat ;staticchar   buffer [ BUFFERSIZE ] ;/* Function is not reentrant.*/char*   ptr ;u_long  databytes ;v_erf = erf;/* wwg: Set error reporting function */if (lseek (wavefile, 0L, SEEK_SET)) {err("%s",strerror(errno));/* wwg: Report error */return  WR_BADSEEK ;}read (wavefile, buffer, BUFFERSIZE) ;if (findchunk (buffer, "RIFF", BUFFERSIZE) != buffer) {err("Bad format: Cannot find RIFF file marker");/* wwg: Report error */return  WR_BADRIFF ;}if (! findchunk (buffer, "WAVE", BUFFERSIZE)) {err("Bad format: Cannot find WAVE file marker");/* wwg: report error */return  WR_BADWAVE ;}ptr = findchunk (buffer, "fmt ", BUFFERSIZE) ;if (! ptr) {err("Bad format: Cannot find 'fmt' file marker");/* wwg: report error */return  WR_BADFORMAT ;}ptr += 4 ;/* Move past "fmt ".*/memcpy (&waveformat, ptr, sizeof (WAVEFORMAT)) ;if (waveformat.dwSize < (sizeof (WAVEFORMAT) - sizeof (u_long))) {err("Bad format: Bad fmt size");/* wwg: report error */return  WR_BADFORMATSIZE ;}if (waveformat.wFormatTag != PCM_WAVE_FORMAT) {err("Only supports PCM wave format");/* wwg: report error */return  WR_NOTPCMFORMAT ;}ptr = findchunk (buffer, "data", BUFFERSIZE) ;if (! ptr) {err("Bad format: unable to find 'data' file marker");/* wwg: report error */return  WR_NODATACHUNK ;}ptr += 4 ;/* Move past "data".*/memcpy (&databytes, ptr, sizeof (u_long)) ;/* Everything is now cool, so fill in output data.*/*channels   = waveformat.wChannels ;*samplerate = waveformat.dwSamplesPerSec ;*samplebits = waveformat.wBitsPerSample ;*samples    = databytes / waveformat.wBlockAlign ;*datastart  = ((u_long) (ptr + 4)) - ((u_long) (&(buffer[0]))) ;if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wBlockAlign) {err("Bad file format");/* wwg: report error */return  WR_BADFORMATDATA ;}if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wChannels / ((waveformat.wBitsPerSample == 16) ? 2 : 1)) {err("Bad file format");/* wwg: report error */return  WR_BADFORMATDATA ;}  return  0 ;} ; /* WaveReadHeader*//*===========================================================================================*/#if 0char*  WaveFileError (int  errno){switch (errno){caseWW_BADOUTPUTFILE: return "Bad output file.\n" ;caseWW_BADWRITEHEADER : return "Not able to write WAV header.\n" ;caseWR_BADALLOC: return "Not able to allocate memory.\n" ;caseWR_BADSEEK        : return "fseek failed.\n" ;caseWR_BADRIFF        : return "Not able to find 'RIFF' file marker.\n" ;caseWR_BADWAVE        : return "Not able to find 'WAVE' file marker.\n" ;caseWR_BADFORMAT      : return "Not able to find 'fmt ' file marker.\n" ;caseWR_BADFORMATSIZE  : return "Format size incorrect.\n" ;caseWR_NOTPCMFORMAT: return "Not PCM format WAV file.\n" ;caseWR_NODATACHUNK: return "Not able to find 'data' file marker.\n" ;caseWR_BADFORMATDATA: return "Format data questionable.\n" ;default           :  return "No error\n" ;} ;returnNULL ;} ; /* WaveFileError*/#endif/*===========================================================================================*/char* findchunk  (char* pstart, char* fourcc, size_t n){char*pend ;intk, test ;pend = pstart + n ;while (pstart < pend){ if (*pstart == *fourcc)       /* found match for first char*/{test = TRUE ;for (k = 1 ; fourcc [k] != 0 ; k++)test = (test ? ( pstart [k] == fourcc [k] ) : FALSE) ;if (test)return  pstart ;} ; /* if*/pstart ++ ;} ; /* while lpstart*/return  NULL ;} ; /* findchuck*//* $Source: /cvsroot/wavplay/code/wavfile.c,v $ */


I will not analyze the specific decoding analysis. The code is not very difficult. As for other parts of the code, it will not be posted. You can download the code for analysis. I downloaded version 1.5B, and the latest version is version 2.0.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.