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