1 /*____________________________________________________________________________
2 
3 	FreeAmp - The Free MP3 Player
4 
5         MP3 Decoder originally Copyright (C) 1995-1997 Xing Technology
6         Corp.  http://www.xingtech.com
7 
8 	Portions Copyright (C) 1998-1999 EMusic.com
9 
10 	This program is free software; you can redistribute it and/or modify
11 	it under the terms of the GNU General Public License as published by
12 	the Free Software Foundation; either version 2 of the License, or
13 	(at your option) any later version.
14 
15 	This program is distributed in the hope that it will be useful,
16 	but WITHOUT ANY WARRANTY; without even the implied warranty of
17 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 	GNU General Public License for more details.
19 
20 	You should have received a copy of the GNU General Public License
21 	along with this program; if not, write to the Free Software
22 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 
24 	$Id: wavep.c,v 1.4 2000/10/13 14:29:03 ijr Exp $
25 ____________________________________________________________________________*/
26 
27 /*---- wavep.c --------------------------------------------
28 
29 WAVE FILE HEADER ROUTINES
30 with conditional pcm conversion to MS wave format
31 portable version
32 
33 -----------------------------------------------------------*/
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <float.h>
37 #include <math.h>
38 #ifdef WIN32
39 #include <io.h>
40 #else
41 #include <unistd.h>
42 #endif
43 #include "port.h"
44 
45 typedef struct
46 {
47    unsigned char riff[4];
48    unsigned char size[4];
49    unsigned char wave[4];
50    unsigned char fmt[4];
51    unsigned char fmtsize[4];
52    unsigned char tag[2];
53    unsigned char nChannels[2];
54    unsigned char nSamplesPerSec[4];
55    unsigned char nAvgBytesPerSec[4];
56    unsigned char nBlockAlign[2];
57    unsigned char nBitsPerSample[2];
58    unsigned char data[4];
59    unsigned char pcm_bytes[4];
60 }
61 BYTE_WAVE;
62 
63 static BYTE_WAVE wave =
64 {
65    "RIFF",
66    {(sizeof(BYTE_WAVE) - 8), 0, 0, 0},
67    "WAVE",
68    "fmt ",
69    {16, 0, 0, 0},
70    {1, 0},
71    {1, 0},
72    {34, 86, 0, 0},		/* 86 * 256 + 34 = 22050 */
73    {172, 68, 0, 0},		/* 172 * 256 + 68 = 44100 */
74    {2, 0},
75    {16, 0},
76    "data",
77    {0, 0, 0, 0}
78 };
79 
80 /*---------------------------------------------------------*/
set_wave(unsigned char w[],int n,long x)81 static void set_wave(unsigned char w[], int n, long x)
82 {
83    int i;
84 
85    for (i = 0; i < n; i++)
86    {
87       w[i] = (unsigned char) (x & 0xff);
88       x >>= 8;
89    }
90 }
91 /*---------------------------------------------------------*/
write_pcm_header_wave(int handout,long samprate,int channels,int bits,int type)92 int write_pcm_header_wave(int handout,
93 			  long samprate, int channels, int bits, int type)
94 {
95    int nwrite;
96 
97    if (type == 0)
98       set_wave(wave.tag, sizeof(wave.tag), 1);
99    else if (type == 10)
100       set_wave(wave.tag, sizeof(wave.tag), 7);
101    else
102       return 0;
103 
104    set_wave(wave.size, sizeof(wave.size), sizeof(wave) - 8);
105    set_wave(wave.nChannels, sizeof(wave.nChannels), channels);
106    set_wave(wave.nSamplesPerSec, sizeof(wave.nSamplesPerSec), samprate);
107    set_wave(wave.nAvgBytesPerSec, sizeof(wave.nAvgBytesPerSec),
108 	    (channels * samprate * bits + 7) / 8);
109    set_wave(wave.nBlockAlign, sizeof(wave.nBlockAlign), (channels * bits + 7) / 8);
110    set_wave(wave.nBitsPerSample, sizeof(wave.nBitsPerSample), bits);
111    set_wave(wave.pcm_bytes, sizeof(wave.pcm_bytes), 0);
112 
113    nwrite = write(handout, &wave, sizeof(wave));
114    if (nwrite != sizeof(wave))
115       return 0;
116 
117    return 1;
118 }
119 /*-----------------------------------------------*/
write_pcm_tailer_wave(int handout,unsigned long pcm_bytes)120 int write_pcm_tailer_wave(int handout, unsigned long pcm_bytes)
121 {
122    unsigned long pos;
123    int nwrite;
124 
125 
126    set_wave(wave.size, sizeof(wave.size), sizeof(wave) - 8 + pcm_bytes);
127    set_wave(wave.pcm_bytes, sizeof(wave.pcm_bytes), pcm_bytes);
128 
129 
130    pos = lseek(handout, 0L, 2);
131 /*-- save current position */
132    lseek(handout, 0L, 0);
133 /*-- pos to header --*/
134    nwrite = write(handout, &wave, sizeof(wave));
135    lseek(handout, pos, 0);
136 /*-- restore pos --*/
137 
138    if (nwrite != sizeof(wave))
139       return 0;
140    return 1;
141 }
142 /*-----------------------------------------------*/
143 /*----------------------------------------------------------------
144   pcm conversion to wave format
145 
146   This conversion code required for big endian machine, or,
147   if sizeof(short) != 16 bits.
148   Conversion routines may be used on any machine, but if
149   not required, the do nothing macros in port.h can be used instead
150   to reduce overhead.
151 
152 -----------------------------------------------------------------*/
153 #ifndef LITTLE_SHORT16
154 #include "wcvt.c"
155 #endif
156 /*-----------------------------------------------*/
cvt_to_wave_test()157 int cvt_to_wave_test()
158 {
159 /*-- test for valid compile ---*/
160 
161    return sizeof(short) - 2;
162 
163 
164 }
165 /*-----------------------------------------------*/
166