2 ** Copyright (C) 2005-2010 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** All rights reserved.
6 ** Redistribution and use in source and binary forms, with or without
7 ** modification, are permitted provided that the following conditions are
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
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.
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.
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
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.
43 ** sndfile.hh -- A lightweight C++ wrapper for the libsndfile API.
45 ** All the methods are inlines and all functionality is contained in this
46 ** file. There is no separate implementation file.
48 ** API documentation is in the doc/ directory of the source code tarball
49 ** and at http://www.mega-nerd.com/libsndfile/api.html.
58 #include <new> // for std::nothrow
63 { SNDFILE_ref (void) ;
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 (void) ;
84 SndfileHandle (const SndfileHandle
&orig
) ;
85 SndfileHandle
& operator = (const SndfileHandle
&rhs
) ;
87 /* Mainly for debugging/testing. */
88 int refCount (void) const { return (p
== NULL
) ? 0 : p
->ref
; }
90 operator bool () const { return (p
!= NULL
) ; }
92 bool operator == (const SndfileHandle
&rhs
) const { return (p
== rhs
.p
) ; }
94 sf_count_t
frames (void) const { return p
? p
->sfinfo
.frames
: 0 ; }
95 int format (void) const { return p
? p
->sfinfo
.format
: 0 ; }
96 int channels (void) const { return p
? p
->sfinfo
.channels
: 0 ; }
97 int samplerate (void) const { return p
? p
->sfinfo
.samplerate
: 0 ; }
99 int error (void) const ;
100 const char * strError (void) const ;
102 int command (int cmd
, void *data
, int datasize
) ;
104 sf_count_t
seek (sf_count_t frames
, int whence
) ;
106 void writeSync (void) ;
108 int setString (int str_type
, const char* str
) ;
110 const char* getString (int str_type
) const ;
112 static int formatCheck (int format
, int channels
, int samplerate
) ;
114 sf_count_t
read (short *ptr
, sf_count_t items
) ;
115 sf_count_t
read (int *ptr
, sf_count_t items
) ;
116 sf_count_t
read (float *ptr
, sf_count_t items
) ;
117 sf_count_t
read (double *ptr
, sf_count_t items
) ;
119 sf_count_t
write (const short *ptr
, sf_count_t items
) ;
120 sf_count_t
write (const int *ptr
, sf_count_t items
) ;
121 sf_count_t
write (const float *ptr
, sf_count_t items
) ;
122 sf_count_t
write (const double *ptr
, sf_count_t items
) ;
124 sf_count_t
readf (short *ptr
, sf_count_t frames
) ;
125 sf_count_t
readf (int *ptr
, sf_count_t frames
) ;
126 sf_count_t
readf (float *ptr
, sf_count_t frames
) ;
127 sf_count_t
readf (double *ptr
, sf_count_t frames
) ;
129 sf_count_t
writef (const short *ptr
, sf_count_t frames
) ;
130 sf_count_t
writef (const int *ptr
, sf_count_t frames
) ;
131 sf_count_t
writef (const float *ptr
, sf_count_t frames
) ;
132 sf_count_t
writef (const double *ptr
, sf_count_t frames
) ;
134 sf_count_t
readRaw (void *ptr
, sf_count_t bytes
) ;
135 sf_count_t
writeRaw (const void *ptr
, sf_count_t bytes
) ;
137 SNDFILE
* rawHandle(void); /**< raw access to the handle. SndfileHandle keeps ownership */
138 SNDFILE
* takeOwnership(void); /**< take ownership of handle, iff reference count is 1 */
141 /*==============================================================================
142 ** Nothing but implementation below.
146 SndfileHandle::SNDFILE_ref::SNDFILE_ref (void)
151 SndfileHandle::SNDFILE_ref::~SNDFILE_ref (void)
152 { if (sf
!= NULL
) sf_close (sf
) ; }
155 SndfileHandle::SndfileHandle (const char *path
, int mode
, int fmt
, int chans
, int srate
)
158 p
= new (std::nothrow
) SNDFILE_ref () ;
163 p
->sfinfo
.frames
= 0 ;
164 p
->sfinfo
.channels
= chans
;
165 p
->sfinfo
.format
= fmt
;
166 p
->sfinfo
.samplerate
= srate
;
167 p
->sfinfo
.sections
= 0 ;
168 p
->sfinfo
.seekable
= 0 ;
170 p
->sf
= sf_open (path
, mode
, &p
->sfinfo
) ;
174 } /* SndfileHandle const char * constructor */
177 SndfileHandle::SndfileHandle (std::string
const & path
, int mode
, int fmt
, int chans
, int srate
)
180 p
= new (std::nothrow
) SNDFILE_ref () ;
185 p
->sfinfo
.frames
= 0 ;
186 p
->sfinfo
.channels
= chans
;
187 p
->sfinfo
.format
= fmt
;
188 p
->sfinfo
.samplerate
= srate
;
189 p
->sfinfo
.sections
= 0 ;
190 p
->sfinfo
.seekable
= 0 ;
192 p
->sf
= sf_open (path
.c_str (), mode
, &p
->sfinfo
) ;
196 } /* SndfileHandle std::string constructor */
199 SndfileHandle::SndfileHandle (int fd
, bool close_desc
, int mode
, int fmt
, int chans
, int srate
)
205 p
= new (std::nothrow
) SNDFILE_ref () ;
210 p
->sfinfo
.frames
= 0 ;
211 p
->sfinfo
.channels
= chans
;
212 p
->sfinfo
.format
= fmt
;
213 p
->sfinfo
.samplerate
= srate
;
214 p
->sfinfo
.sections
= 0 ;
215 p
->sfinfo
.seekable
= 0 ;
217 p
->sf
= sf_open_fd (fd
, mode
, &p
->sfinfo
, close_desc
) ;
221 } /* SndfileHandle fd constructor */
224 SndfileHandle::~SndfileHandle (void)
225 { if (p
!= NULL
&& --p
->ref
== 0)
227 } /* SndfileHandle destructor */
231 SndfileHandle::SndfileHandle (const SndfileHandle
&orig
)
235 } /* SndfileHandle copy constructor */
237 inline SndfileHandle
&
238 SndfileHandle::operator = (const SndfileHandle
&rhs
)
242 if (p
!= NULL
&& --p
->ref
== 0)
250 } /* SndfileHandle assignment operator */
253 SndfileHandle::error (void) const
254 { return sf_error (p
->sf
) ; }
257 SndfileHandle::strError (void) const
258 { return sf_strerror (p
->sf
) ; }
261 SndfileHandle::command (int cmd
, void *data
, int datasize
)
262 { return sf_command (p
->sf
, cmd
, data
, datasize
) ; }
265 SndfileHandle::seek (sf_count_t frame_count
, int whence
)
266 { return sf_seek (p
->sf
, frame_count
, whence
) ; }
269 SndfileHandle::writeSync (void)
270 { sf_write_sync (p
->sf
) ; }
273 SndfileHandle::setString (int str_type
, const char* str
)
274 { return sf_set_string (p
->sf
, str_type
, str
) ; }
277 SndfileHandle::getString (int str_type
) const
278 { return sf_get_string (p
->sf
, str_type
) ; }
281 SndfileHandle::formatCheck (int fmt
, int chans
, int srate
)
286 sfinfo
.channels
= chans
;
287 sfinfo
.format
= fmt
;
288 sfinfo
.samplerate
= srate
;
289 sfinfo
.sections
= 0 ;
290 sfinfo
.seekable
= 0 ;
292 return sf_format_check (&sfinfo
) ;
295 /*---------------------------------------------------------------------*/
298 SndfileHandle::read (short *ptr
, sf_count_t items
)
299 { return sf_read_short (p
->sf
, ptr
, items
) ; }
302 SndfileHandle::read (int *ptr
, sf_count_t items
)
303 { return sf_read_int (p
->sf
, ptr
, items
) ; }
306 SndfileHandle::read (float *ptr
, sf_count_t items
)
307 { return sf_read_float (p
->sf
, ptr
, items
) ; }
310 SndfileHandle::read (double *ptr
, sf_count_t items
)
311 { return sf_read_double (p
->sf
, ptr
, items
) ; }
314 SndfileHandle::write (const short *ptr
, sf_count_t items
)
315 { return sf_write_short (p
->sf
, ptr
, items
) ; }
318 SndfileHandle::write (const int *ptr
, sf_count_t items
)
319 { return sf_write_int (p
->sf
, ptr
, items
) ; }
322 SndfileHandle::write (const float *ptr
, sf_count_t items
)
323 { return sf_write_float (p
->sf
, ptr
, items
) ; }
326 SndfileHandle::write (const double *ptr
, sf_count_t items
)
327 { return sf_write_double (p
->sf
, ptr
, items
) ; }
330 SndfileHandle::readf (short *ptr
, sf_count_t frame_count
)
331 { return sf_readf_short (p
->sf
, ptr
, frame_count
) ; }
334 SndfileHandle::readf (int *ptr
, sf_count_t frame_count
)
335 { return sf_readf_int (p
->sf
, ptr
, frame_count
) ; }
338 SndfileHandle::readf (float *ptr
, sf_count_t frame_count
)
339 { return sf_readf_float (p
->sf
, ptr
, frame_count
) ; }
342 SndfileHandle::readf (double *ptr
, sf_count_t frame_count
)
343 { return sf_readf_double (p
->sf
, ptr
, frame_count
) ; }
346 SndfileHandle::writef (const short *ptr
, sf_count_t frame_count
)
347 { return sf_writef_short (p
->sf
, ptr
, frame_count
) ; }
350 SndfileHandle::writef (const int *ptr
, sf_count_t frame_count
)
351 { return sf_writef_int (p
->sf
, ptr
, frame_count
) ; }
354 SndfileHandle::writef (const float *ptr
, sf_count_t frame_count
)
355 { return sf_writef_float (p
->sf
, ptr
, frame_count
) ; }
358 SndfileHandle::writef (const double *ptr
, sf_count_t frame_count
)
359 { return sf_writef_double (p
->sf
, ptr
, frame_count
) ; }
362 SndfileHandle::readRaw (void *ptr
, sf_count_t bytes
)
363 { return sf_read_raw (p
->sf
, ptr
, bytes
) ; }
366 SndfileHandle::writeRaw (const void *ptr
, sf_count_t bytes
)
367 { return sf_write_raw (p
->sf
, ptr
, bytes
) ; }
370 SndfileHandle::rawHandle(void)
379 SndfileHandle::takeOwnership(void)
381 if (!p
|| (p
->ref
!= 1))
384 SNDFILE
* ret
= p
->sf
;
391 #ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
394 SndfileHandle::SndfileHandle (LPCWSTR wpath
, int mode
, int fmt
, int chans
, int srate
)
397 p
= new (std::nothrow
) SNDFILE_ref () ;
402 p
->sfinfo
.frames
= 0 ;
403 p
->sfinfo
.channels
= chans
;
404 p
->sfinfo
.format
= fmt
;
405 p
->sfinfo
.samplerate
= srate
;
406 p
->sfinfo
.sections
= 0 ;
407 p
->sfinfo
.seekable
= 0 ;
409 p
->sf
= sf_wchar_open (wpath
, mode
, &p
->sfinfo
) ;
413 } /* SndfileHandle const wchar_t * constructor */
417 #endif /* SNDFILE_HH */