Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
270 cycrow 1
/*
2
** Copyright (C) 2005-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
3
**
4
** All rights reserved.
5
**
6
** Redistribution and use in source and binary forms, with or without
7
** modification, are permitted provided that the following conditions are
8
** met:
9
**
10
**     * Redistributions of source code must retain the above copyright
11
**       notice, this list of conditions and the following disclaimer.
12
**     * Redistributions in binary form must reproduce the above copyright
13
**       notice, this list of conditions and the following disclaimer in
14
**       the documentation and/or other materials provided with the
15
**       distribution.
16
**     * Neither the author nor the names of any contributors may be used
17
**       to endorse or promote products derived from this software without
18
**       specific prior written permission.
19
**
20
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22
** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27
** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30
** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
 
33
/*
34
** The above modified BSD style license (GPL and LGPL compatible) applies to
35
** this file. It does not apply to libsndfile itself which is released under
36
** the GNU LGPL or the libsndfile test suite which is released under the GNU
37
** GPL.
38
** This means that this header file can be used under this modified BSD style
39
** license, but the LGPL still holds for the libsndfile library itself.
40
*/
41
 
42
/*
43
** sndfile.hh -- A lightweight C++ wrapper for the libsndfile API.
44
**
45
** All the methods are inlines and all functionality is contained in this
46
** file. There is no separate implementation file.
47
**
48
** API documentation is in the doc/ directory of the source code tarball
49
** and at http://www.mega-nerd.com/libsndfile/api.html.
50
*/
51
 
52
#ifndef SNDFILE_HH
53
#define SNDFILE_HH
54
 
55
#include "sndfile.h"
56
 
57
#include <string>
58
#include <new> // for std::nothrow
59
 
60
class SndfileHandle
61
{	private :
62
		struct SNDFILE_ref
63
		{	SNDFILE_ref (void) ;
64
			~SNDFILE_ref (void) ;
65
 
66
			SNDFILE *sf ;
67
			SF_INFO sfinfo ;
68
			int ref ;
69
			} ;
70
 
71
		SNDFILE_ref *p ;
72
 
73
	public :
74
			/* Default constructor */
75
			SndfileHandle (void) : p (NULL) {} ;
76
			SndfileHandle (const char *path, int mode = SFM_READ,
77
							int format = 0, int channels = 0, int samplerate = 0) ;
78
			SndfileHandle (std::string const & path, int mode = SFM_READ,
79
							int format = 0, int channels = 0, int samplerate = 0) ;
80
			SndfileHandle (int fd, bool close_desc, int mode = SFM_READ,
81
							int format = 0, int channels = 0, int samplerate = 0) ;
82
			SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mode = SFM_READ,
83
							int format = 0, int channels = 0, int samplerate = 0) ;
84
 
85
#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
86
			SndfileHandle (LPCWSTR wpath, int mode = SFM_READ,
87
							int format = 0, int channels = 0, int samplerate = 0) ;
88
#endif
89
 
90
			~SndfileHandle (void) ;
91
 
92
			SndfileHandle (const SndfileHandle &orig) ;
93
			SndfileHandle & operator = (const SndfileHandle &rhs) ;
94
 
95
		/* Mainly for debugging/testing. */
96
		int refCount (void) const { return (p == NULL) ? 0 : p->ref ; }
97
 
98
		operator bool () const { return (p != NULL) ; }
99
 
100
		bool operator == (const SndfileHandle &rhs) const { return (p == rhs.p) ; }
101
 
102
		sf_count_t	frames (void) const		{ return p ? p->sfinfo.frames : 0 ; }
103
		int			format (void) const		{ return p ? p->sfinfo.format : 0 ; }
104
		int			channels (void) const	{ return p ? p->sfinfo.channels : 0 ; }
105
		int			samplerate (void) const { return p ? p->sfinfo.samplerate : 0 ; }
106
 
107
		int error (void) const ;
108
		const char * strError (void) const ;
109
 
110
		int command (int cmd, void *data, int datasize) ;
111
 
112
		sf_count_t	seek (sf_count_t frames, int whence) ;
113
 
114
		void writeSync (void) ;
115
 
116
		int setString (int str_type, const char* str) ;
117
 
118
		const char* getString (int str_type) const ;
119
 
120
		static int formatCheck (int format, int channels, int samplerate) ;
121
 
122
		sf_count_t read (short *ptr, sf_count_t items) ;
123
		sf_count_t read (int *ptr, sf_count_t items) ;
124
		sf_count_t read (float *ptr, sf_count_t items) ;
125
		sf_count_t read (double *ptr, sf_count_t items) ;
126
 
127
		sf_count_t write (const short *ptr, sf_count_t items) ;
128
		sf_count_t write (const int *ptr, sf_count_t items) ;
129
		sf_count_t write (const float *ptr, sf_count_t items) ;
130
		sf_count_t write (const double *ptr, sf_count_t items) ;
131
 
132
		sf_count_t readf (short *ptr, sf_count_t frames) ;
133
		sf_count_t readf (int *ptr, sf_count_t frames) ;
134
		sf_count_t readf (float *ptr, sf_count_t frames) ;
135
		sf_count_t readf (double *ptr, sf_count_t frames) ;
136
 
137
		sf_count_t writef (const short *ptr, sf_count_t frames) ;
138
		sf_count_t writef (const int *ptr, sf_count_t frames) ;
139
		sf_count_t writef (const float *ptr, sf_count_t frames) ;
140
		sf_count_t writef (const double *ptr, sf_count_t frames) ;
141
 
142
		sf_count_t	readRaw		(void *ptr, sf_count_t bytes) ;
143
		sf_count_t	writeRaw	(const void *ptr, sf_count_t bytes) ;
144
 
145
		/**< Raw access to the handle. SndfileHandle keeps ownership. */
146
		SNDFILE * rawHandle (void) ;
147
 
148
		/**< Take ownership of handle, if reference count is 1. */
149
		SNDFILE * takeOwnership (void) ;
150
} ;
151
 
152
/*==============================================================================
153
**	Nothing but implementation below.
154
*/
155
 
156
inline
157
SndfileHandle::SNDFILE_ref::SNDFILE_ref (void)
158
: sf (NULL), sfinfo (), ref (1)
159
{}
160
 
161
inline
162
SndfileHandle::SNDFILE_ref::~SNDFILE_ref (void)
163
{	if (sf != NULL) sf_close (sf) ; }
164
 
165
inline
166
SndfileHandle::SndfileHandle (const char *path, int mode, int fmt, int chans, int srate)
167
: p (NULL)
168
{
169
	p = new (std::nothrow) SNDFILE_ref () ;
170
 
171
	if (p != NULL)
172
	{	p->ref = 1 ;
173
 
174
		p->sfinfo.frames = 0 ;
175
		p->sfinfo.channels = chans ;
176
		p->sfinfo.format = fmt ;
177
		p->sfinfo.samplerate = srate ;
178
		p->sfinfo.sections = 0 ;
179
		p->sfinfo.seekable = 0 ;
180
 
181
		p->sf = sf_open (path, mode, &p->sfinfo) ;
182
		} ;
183
 
184
	return ;
185
} /* SndfileHandle const char * constructor */
186
 
187
inline
188
SndfileHandle::SndfileHandle (std::string const & path, int mode, int fmt, int chans, int srate)
189
: p (NULL)
190
{
191
	p = new (std::nothrow) SNDFILE_ref () ;
192
 
193
	if (p != NULL)
194
	{	p->ref = 1 ;
195
 
196
		p->sfinfo.frames = 0 ;
197
		p->sfinfo.channels = chans ;
198
		p->sfinfo.format = fmt ;
199
		p->sfinfo.samplerate = srate ;
200
		p->sfinfo.sections = 0 ;
201
		p->sfinfo.seekable = 0 ;
202
 
203
		p->sf = sf_open (path.c_str (), mode, &p->sfinfo) ;
204
		} ;
205
 
206
	return ;
207
} /* SndfileHandle std::string constructor */
208
 
209
inline
210
SndfileHandle::SndfileHandle (int fd, bool close_desc, int mode, int fmt, int chans, int srate)
211
: p (NULL)
212
{
213
	if (fd < 0)
214
		return ;
215
 
216
	p = new (std::nothrow) SNDFILE_ref () ;
217
 
218
	if (p != NULL)
219
	{	p->ref = 1 ;
220
 
221
		p->sfinfo.frames = 0 ;
222
		p->sfinfo.channels = chans ;
223
		p->sfinfo.format = fmt ;
224
		p->sfinfo.samplerate = srate ;
225
		p->sfinfo.sections = 0 ;
226
		p->sfinfo.seekable = 0 ;
227
 
228
		p->sf = sf_open_fd (fd, mode, &p->sfinfo, close_desc) ;
229
		} ;
230
 
231
	return ;
232
} /* SndfileHandle fd constructor */
233
 
234
inline
235
SndfileHandle::SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mode, int fmt, int chans, int srate)
236
: p (NULL)
237
{
238
	p = new (std::nothrow) SNDFILE_ref () ;
239
 
240
	if (p != NULL)
241
	{	p->ref = 1 ;
242
 
243
		p->sfinfo.frames = 0 ;
244
		p->sfinfo.channels = chans ;
245
		p->sfinfo.format = fmt ;
246
		p->sfinfo.samplerate = srate ;
247
		p->sfinfo.sections = 0 ;
248
		p->sfinfo.seekable = 0 ;
249
 
250
		p->sf = sf_open_virtual (&sfvirtual, mode, &p->sfinfo, user_data) ;
251
		} ;
252
 
253
	return ;
254
} /* SndfileHandle std::string constructor */
255
 
256
inline
257
SndfileHandle::~SndfileHandle (void)
258
{	if (p != NULL && --p->ref == 0)
259
		delete p ;
260
} /* SndfileHandle destructor */
261
 
262
 
263
inline
264
SndfileHandle::SndfileHandle (const SndfileHandle &orig)
265
: p (orig.p)
266
{	if (p != NULL)
267
		++p->ref ;
268
} /* SndfileHandle copy constructor */
269
 
270
inline SndfileHandle &
271
SndfileHandle::operator = (const SndfileHandle &rhs)
272
{
273
	if (&rhs == this)
274
		return *this ;
275
	if (p != NULL && --p->ref == 0)
276
		delete p ;
277
 
278
	p = rhs.p ;
279
	if (p != NULL)
280
		++p->ref ;
281
 
282
	return *this ;
283
} /* SndfileHandle assignment operator */
284
 
285
inline int
286
SndfileHandle::error (void) const
287
{	return sf_error (p->sf) ; }
288
 
289
inline const char *
290
SndfileHandle::strError (void) const
291
{	return sf_strerror (p->sf) ; }
292
 
293
inline int
294
SndfileHandle::command (int cmd, void *data, int datasize)
295
{	return sf_command (p->sf, cmd, data, datasize) ; }
296
 
297
inline sf_count_t
298
SndfileHandle::seek (sf_count_t frame_count, int whence)
299
{	return sf_seek (p->sf, frame_count, whence) ; }
300
 
301
inline void
302
SndfileHandle::writeSync (void)
303
{	sf_write_sync (p->sf) ; }
304
 
305
inline int
306
SndfileHandle::setString (int str_type, const char* str)
307
{	return sf_set_string (p->sf, str_type, str) ; }
308
 
309
inline const char*
310
SndfileHandle::getString (int str_type) const
311
{	return sf_get_string (p->sf, str_type) ; }
312
 
313
inline int
314
SndfileHandle::formatCheck (int fmt, int chans, int srate)
315
{
316
	SF_INFO sfinfo ;
317
 
318
	sfinfo.frames = 0 ;
319
	sfinfo.channels = chans ;
320
	sfinfo.format = fmt ;
321
	sfinfo.samplerate = srate ;
322
	sfinfo.sections = 0 ;
323
	sfinfo.seekable = 0 ;
324
 
325
	return sf_format_check (&sfinfo) ;
326
}
327
 
328
/*---------------------------------------------------------------------*/
329
 
330
inline sf_count_t
331
SndfileHandle::read (short *ptr, sf_count_t items)
332
{	return sf_read_short (p->sf, ptr, items) ; }
333
 
334
inline sf_count_t
335
SndfileHandle::read (int *ptr, sf_count_t items)
336
{	return sf_read_int (p->sf, ptr, items) ; }
337
 
338
inline sf_count_t
339
SndfileHandle::read (float *ptr, sf_count_t items)
340
{	return sf_read_float (p->sf, ptr, items) ; }
341
 
342
inline sf_count_t
343
SndfileHandle::read (double *ptr, sf_count_t items)
344
{	return sf_read_double (p->sf, ptr, items) ; }
345
 
346
inline sf_count_t
347
SndfileHandle::write (const short *ptr, sf_count_t items)
348
{	return sf_write_short (p->sf, ptr, items) ; }
349
 
350
inline sf_count_t
351
SndfileHandle::write (const int *ptr, sf_count_t items)
352
{	return sf_write_int (p->sf, ptr, items) ; }
353
 
354
inline sf_count_t
355
SndfileHandle::write (const float *ptr, sf_count_t items)
356
{	return sf_write_float (p->sf, ptr, items) ; }
357
 
358
inline sf_count_t
359
SndfileHandle::write (const double *ptr, sf_count_t items)
360
{	return sf_write_double (p->sf, ptr, items) ; }
361
 
362
inline sf_count_t
363
SndfileHandle::readf (short *ptr, sf_count_t frame_count)
364
{	return sf_readf_short (p->sf, ptr, frame_count) ; }
365
 
366
inline sf_count_t
367
SndfileHandle::readf (int *ptr, sf_count_t frame_count)
368
{	return sf_readf_int (p->sf, ptr, frame_count) ; }
369
 
370
inline sf_count_t
371
SndfileHandle::readf (float *ptr, sf_count_t frame_count)
372
{	return sf_readf_float (p->sf, ptr, frame_count) ; }
373
 
374
inline sf_count_t
375
SndfileHandle::readf (double *ptr, sf_count_t frame_count)
376
{	return sf_readf_double (p->sf, ptr, frame_count) ; }
377
 
378
inline sf_count_t
379
SndfileHandle::writef (const short *ptr, sf_count_t frame_count)
380
{	return sf_writef_short (p->sf, ptr, frame_count) ; }
381
 
382
inline sf_count_t
383
SndfileHandle::writef (const int *ptr, sf_count_t frame_count)
384
{	return sf_writef_int (p->sf, ptr, frame_count) ; }
385
 
386
inline sf_count_t
387
SndfileHandle::writef (const float *ptr, sf_count_t frame_count)
388
{	return sf_writef_float (p->sf, ptr, frame_count) ; }
389
 
390
inline sf_count_t
391
SndfileHandle::writef (const double *ptr, sf_count_t frame_count)
392
{	return sf_writef_double (p->sf, ptr, frame_count) ; }
393
 
394
inline sf_count_t
395
SndfileHandle::readRaw (void *ptr, sf_count_t bytes)
396
{	return sf_read_raw (p->sf, ptr, bytes) ; }
397
 
398
inline sf_count_t
399
SndfileHandle::writeRaw (const void *ptr, sf_count_t bytes)
400
{	return sf_write_raw (p->sf, ptr, bytes) ; }
401
 
402
inline SNDFILE *
403
SndfileHandle::rawHandle (void)
404
{	return (p ? p->sf : NULL) ; }
405
 
406
inline SNDFILE *
407
SndfileHandle::takeOwnership (void)
408
{
409
	if (p == NULL || (p->ref != 1))
410
		return NULL ;
411
 
412
	SNDFILE * sf = p->sf ;
413
	p->sf = NULL ;
414
	delete p ;
415
	p = NULL ;
416
	return sf ;
417
}
418
 
419
#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
420
 
421
inline
422
SndfileHandle::SndfileHandle (LPCWSTR wpath, int mode, int fmt, int chans, int srate)
423
: p (NULL)
424
{
425
	p = new (std::nothrow) SNDFILE_ref () ;
426
 
427
	if (p != NULL)
428
	{	p->ref = 1 ;
429
 
430
		p->sfinfo.frames = 0 ;
431
		p->sfinfo.channels = chans ;
432
		p->sfinfo.format = fmt ;
433
		p->sfinfo.samplerate = srate ;
434
		p->sfinfo.sections = 0 ;
435
		p->sfinfo.seekable = 0 ;
436
 
437
		p->sf = sf_wchar_open (wpath, mode, &p->sfinfo) ;
438
		} ;
439
 
440
	return ;
441
} /* SndfileHandle const wchar_t * constructor */
442
 
443
#endif
444
 
445
#endif	/* SNDFILE_HH */
446