aboutsummaryrefslogtreecommitdiff
path: root/src/lib/hd24sndfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hd24sndfile.cpp')
-rw-r--r--src/lib/hd24sndfile.cpp270
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>
6using std::ofstream;
7using std::cout;
8using std::endl;
9hd24sndfile::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
18hd24sndfile::~hd24sndfile()
19{
20 //if (sndfilehandle!=NULL)
21 //{
22 // delete sndfilehandle;
23 //}
24 //if (outfilehandle!=NULL)
25 //{
26 // /delete outfilehandle;
27 //}
28}
29
30int hd24sndfile::handletype()
31{
32 return _handletype;
33}
34
35void* hd24sndfile::handle()
36{
37 if (_handletype==0)
38 {
39 return (void*)sndfilehandle;
40 }
41 return (void*)outfilehandle;
42}
43
44void hd24sndfile::handle(SNDFILE* newhandle)
45{
46 sndfilehandle=newhandle;
47 _handletype=0;
48}
49
50void hd24sndfile::handle(ofstream* newhandle)
51{
52 outfilehandle=newhandle;
53
54 _handletype=1;
55 // TODO: Write empty header (for filling in later)
56}
57
58void 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
69void 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
89void 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}
148void 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
180void 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
261void 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