diff options
Diffstat (limited to 'src/lib/hd24sndfile.cpp')
-rw-r--r-- | src/lib/hd24sndfile.cpp | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/lib/hd24sndfile.cpp b/src/lib/hd24sndfile.cpp new file mode 100644 index 0000000..470a465 --- /dev/null +++ b/src/lib/hd24sndfile.cpp | |||
@@ -0,0 +1,270 @@ | |||
1 | #include "hd24sndfile.h" | ||
2 | #include <sndfile.h> | ||
3 | #include <fstream> | ||
4 | #include <iostream> | ||
5 | #include <convertlib.h> | ||
6 | using std::ofstream; | ||
7 | using std::cout; | ||
8 | using std::endl; | ||
9 | hd24sndfile::hd24sndfile(int p_format,SoundFileWrapper* p_soundfile) | ||
10 | { | ||
11 | sndfilehandle=(SNDFILE*)NULL; | ||
12 | outfilehandle=(ofstream*)NULL; | ||
13 | _handletype=0; // default is 0=libsndfile, 1=native file | ||
14 | sf_format=p_format; | ||
15 | soundfile=p_soundfile; | ||
16 | } | ||
17 | |||
18 | hd24sndfile::~hd24sndfile() | ||
19 | { | ||
20 | //if (sndfilehandle!=NULL) | ||
21 | //{ | ||
22 | // delete sndfilehandle; | ||
23 | //} | ||
24 | //if (outfilehandle!=NULL) | ||
25 | //{ | ||
26 | // /delete outfilehandle; | ||
27 | //} | ||
28 | } | ||
29 | |||
30 | int hd24sndfile::handletype() | ||
31 | { | ||
32 | return _handletype; | ||
33 | } | ||
34 | |||
35 | void* hd24sndfile::handle() | ||
36 | { | ||
37 | if (_handletype==0) | ||
38 | { | ||
39 | return (void*)sndfilehandle; | ||
40 | } | ||
41 | return (void*)outfilehandle; | ||
42 | } | ||
43 | |||
44 | void hd24sndfile::handle(SNDFILE* newhandle) | ||
45 | { | ||
46 | sndfilehandle=newhandle; | ||
47 | _handletype=0; | ||
48 | } | ||
49 | |||
50 | void hd24sndfile::handle(ofstream* newhandle) | ||
51 | { | ||
52 | outfilehandle=newhandle; | ||
53 | |||
54 | _handletype=1; | ||
55 | // TODO: Write empty header (for filling in later) | ||
56 | } | ||
57 | |||
58 | void hd24sndfile::handle(void* newhandle,int htype) | ||
59 | { | ||
60 | _handletype=htype; | ||
61 | if (htype==1) { | ||
62 | outfilehandle=(ofstream*)newhandle; | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | sndfilehandle=(SNDFILE*)newhandle; | ||
67 | } | ||
68 | |||
69 | void hd24sndfile::open(const char* filename,int filemode,SF_INFO* infoblock,SoundFileWrapper* _soundfile) | ||
70 | { | ||
71 | _handletype=0; // soundfile | ||
72 | soundfile=_soundfile; | ||
73 | sfinfo=infoblock; | ||
74 | sndfilehandle=soundfile->sf_open(filename,filemode,infoblock); | ||
75 | outfilehandle=NULL; | ||
76 | |||
77 | if (!sndfilehandle) | ||
78 | { | ||
79 | cout << "Problem opening file with the following specs: " << endl; | ||
80 | cout << "rate=" << infoblock->samplerate << endl; | ||
81 | cout << "frames=" << infoblock->frames << endl; | ||
82 | cout << "channels=" << infoblock->channels << endl; | ||
83 | cout << "sections=" << infoblock->sections << endl; | ||
84 | cout << "seekable=" << infoblock->seekable << endl; | ||
85 | cout << "format=" << infoblock->format << endl; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | void hd24sndfile::open(const char* filename,int filemode,SF_INFO* infoblock) | ||
90 | { | ||
91 | _handletype=1; // iostream | ||
92 | sfinfo=infoblock; | ||
93 | sndfilehandle=NULL; | ||
94 | outfilehandle=new ofstream(filename,ios_base::out|ios_base::trunc|ios_base::binary); | ||
95 | |||
96 | if ((sf_format & 0xFF0000) ==SF_FORMAT_WAV) | ||
97 | { | ||
98 | char buf[44]={ | ||
99 | 'R','I','F','F', 0,0,0,0, 'W','A','V','E', 'f','m','t',' ', | ||
100 | 16,0,0,0, 1,0,1,0, 0,0,0,0, 0,0,0,0, | ||
101 | 3,0,24,0, 'd','a','t','a', 0,0,0,0 | ||
102 | }; | ||
103 | |||
104 | // samplerate follows | ||
105 | long rate=sfinfo->samplerate; // FIXME: Get proper rate from sfinfo | ||
106 | buf[24]=(char)((rate)%256); | ||
107 | buf[25]=(char)(((rate)>>8)%256); | ||
108 | buf[26]=(char)(((rate)>>16)%256); | ||
109 | buf[27]=(char)(((rate)>>24)%256); | ||
110 | |||
111 | rate*=3; | ||
112 | buf[28]=(char)((rate)%256); | ||
113 | buf[29]=(char)(((rate)>>8)%256); | ||
114 | buf[30]=(char)(((rate)>>16)%256); | ||
115 | buf[31]=(char)(((rate)>>24)%256); | ||
116 | |||
117 | outfilehandle->write(buf,44); | ||
118 | return; | ||
119 | |||
120 | } | ||
121 | |||
122 | if ((sf_format & 0xFF0000) ==SF_FORMAT_AIFF) | ||
123 | { | ||
124 | char buf[54]={ | ||
125 | 'F','O','R','M', | ||
126 | 0,0,0,0, /* Bytes that follow in this file */ | ||
127 | 'A','I','F','F', 'C','O','M','M', | ||
128 | 0,0,0,18, /* chunksize */ | ||
129 | 0,1, /*numchannels*/ | ||
130 | 0,0,0,0, /*sampleframes */ | ||
131 | 0,24, /* Samplesize in bits */ | ||
132 | 0,0,0,0,0,0,0,0,0,0, /* sample rate as 80 bit IEEE float */ | ||
133 | 'S','S','N','D', | ||
134 | 0,0,0,0, /* sound block datalen, to be filled afterwards */ | ||
135 | 0,0,0,0, /* offset */ | ||
136 | 0,0,0,0 /* blocksize */ /* -> data follows */ | ||
137 | }; | ||
138 | |||
139 | // samplerate follows | ||
140 | long rate=sfinfo->samplerate; // FIXME: Get proper rate from sfinfo | ||
141 | Convert::setfloat80((unsigned char*)buf,28,rate); | ||
142 | |||
143 | outfilehandle->write(buf,54); | ||
144 | return; | ||
145 | |||
146 | } | ||
147 | } | ||
148 | void hd24sndfile::writerawbuf(unsigned char* buf,__uint32 subblockbytes) | ||
149 | { | ||
150 | if ((sf_format & 0xFF0000) ==SF_FORMAT_AIFF) | ||
151 | { | ||
152 | // and we're doing 24 bits. | ||
153 | for (__uint32 i=0;i<subblockbytes;i+=3) | ||
154 | { | ||
155 | char a=buf[i]; | ||
156 | buf[i]=buf[i+2]; | ||
157 | buf[i+2]=a; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | // maybe we want to do 24->16 bit conversion here | ||
162 | |||
163 | if (sndfilehandle != NULL) | ||
164 | { | ||
165 | #if (HD24DEBUG==1) | ||
166 | cout << "soundfile=" << soundfile <<endl; | ||
167 | #endif | ||
168 | #if (HD24DEBUG==1) | ||
169 | cout << "soundfile->sf_write_raw(sndfilehandle,buf,subblockbytes);" << endl; | ||
170 | #endif | ||
171 | soundfile->sf_write_raw(sndfilehandle,buf,subblockbytes); | ||
172 | return; | ||
173 | } | ||
174 | if (outfilehandle!=NULL) | ||
175 | { | ||
176 | outfilehandle->write((const char*)buf,subblockbytes); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void hd24sndfile::close() | ||
181 | { | ||
182 | if (sndfilehandle != NULL) | ||
183 | { | ||
184 | soundfile->sf_close(sndfilehandle); | ||
185 | return; | ||
186 | } | ||
187 | if (outfilehandle == NULL) return; | ||
188 | |||
189 | |||
190 | switch (sf_format & 0xFF0000) | ||
191 | { | ||
192 | case SF_FORMAT_WAV: | ||
193 | { | ||
194 | // TODO: set sample rate, len, etc. in header | ||
195 | long pos=outfilehandle->tellp(); | ||
196 | char bufword[4]; | ||
197 | bufword[0]=(char)((pos-8)%256); | ||
198 | bufword[1]=(char)(((pos-8)>>8)%256); | ||
199 | bufword[2]=(char)(((pos-8)>>16)%256); | ||
200 | bufword[3]=(char)(((pos-8)>>24)%256); | ||
201 | outfilehandle->seekp(4); | ||
202 | outfilehandle->write(bufword,4); | ||
203 | |||
204 | bufword[0]=(char)((pos-44)%256); | ||
205 | bufword[1]=(char)(((pos-44)>>8)%256); | ||
206 | bufword[2]=(char)(((pos-44)>>16)%256); | ||
207 | bufword[3]=(char)(((pos-44)>>24)%256); | ||
208 | outfilehandle->seekp(40); | ||
209 | outfilehandle->write(bufword,4); | ||
210 | |||
211 | outfilehandle->close(); | ||
212 | break; | ||
213 | } | ||
214 | case SF_FORMAT_AIFF: | ||
215 | { | ||
216 | long pos=outfilehandle->tellp(); | ||
217 | char bufword[4]; | ||
218 | bufword[3]=(char)((pos-8)%256); | ||
219 | bufword[2]=(char)(((pos-8)>>8)%256); | ||
220 | bufword[1]=(char)(((pos-8)>>16)%256); | ||
221 | bufword[0]=(char)(((pos-8)>>24)%256); | ||
222 | |||
223 | outfilehandle->seekp(4); | ||
224 | outfilehandle->write(bufword,4); | ||
225 | |||
226 | long chunksize=(pos-46); | ||
227 | long sambytes=chunksize-8; | ||
228 | |||
229 | |||
230 | long samframes=sambytes/3; // Bytes per sample. TODO: Not hardcode this | ||
231 | bufword[3]=(char)(samframes%256); | ||
232 | bufword[2]=(char)((samframes>>8)%256); | ||
233 | bufword[1]=(char)((samframes>>16)%256); | ||
234 | bufword[0]=(char)((samframes>>24)%256); | ||
235 | outfilehandle->seekp(22); | ||
236 | outfilehandle->write(bufword,4); | ||
237 | |||
238 | |||
239 | bufword[3]=(char)(chunksize%256); | ||
240 | bufword[2]=(char)((chunksize>>8)%256); | ||
241 | bufword[1]=(char)((chunksize>>16)%256); | ||
242 | bufword[0]=(char)((chunksize>>24)%256); | ||
243 | outfilehandle->seekp(42); | ||
244 | outfilehandle->write(bufword,4); | ||
245 | |||
246 | |||
247 | |||
248 | outfilehandle->close(); | ||
249 | break; | ||
250 | |||
251 | } | ||
252 | default: | ||
253 | { | ||
254 | outfilehandle->close(); | ||
255 | break; | ||
256 | |||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | void hd24sndfile::write_float(float* buf,__uint32 frames) | ||
262 | { | ||
263 | if (sndfilehandle != NULL) | ||
264 | { | ||
265 | soundfile->sf_write_float(sndfilehandle,buf,frames); | ||
266 | } | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | |||