26 #if defined (HAVE_CONFIG_H)
48 #if defined (HAVE_SNDFILE)
76 #if defined (HAVE_SNDFILE)
78 int nargin = args.length ();
80 if (nargin < 1 || nargin > 3)
83 std::string filename = args(0).xstring_value (
"audioread: FILENAME must be a string");
87 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
90 error (
"audioread: failed to open input file '%s': %s",
91 filename.c_str (), sf_strerror (file));
98 if (info.frames == SF_COUNT_MAX)
99 error (
"audioread: malformed header does not specify number of samples");
103 sf_read_double (file, data, info.frames * info.channels);
105 sf_count_t start = 0;
106 sf_count_t end = info.frames;
108 if ((nargin == 2 && ! args(1).is_string ()) || nargin == 3)
112 if (
range.numel () != 2)
113 error (
"audioread: invalid specification for range of frames");
118 if (dstart < 1 || dstart > dend || dend > info.frames
121 error (
"audioread: invalid specification for range of frames");
127 sf_count_t items = end - start;
129 Matrix audio (items, info.channels);
133 data += start * info.channels;
135 for (
int i = 0; i < items; i++)
137 for (
int channel = 0; channel < info.channels; channel++)
138 paudio[items*channel+i] = *data++;
143 if ((nargin == 2 && args(1).is_string ()) || nargin == 3)
149 type = args(1).string_value ();
151 if (type ==
"native")
153 switch (info.format & SF_FORMAT_SUBMASK)
155 case SF_FORMAT_PCM_S8:
158 case SF_FORMAT_PCM_U8:
161 case SF_FORMAT_PCM_16:
164 case SF_FORMAT_PCM_24:
167 case SF_FORMAT_PCM_32:
170 case SF_FORMAT_FLOAT:
184 return ovl (ret_audio, info.samplerate);
188 octave_unused_parameter (args);
191 "reading and writing sound files through libsndfile");
196 #if defined (HAVE_SNDFILE)
199 extension_to_format (
const std::string& ext)
201 static bool initialized =
false;
203 static std::map<std::string, int> table;
207 table[
"wav"] = SF_FORMAT_WAV;
208 table[
"aiff"] = SF_FORMAT_AIFF;
209 table[
"au"] = SF_FORMAT_AU;
210 table[
"raw"] = SF_FORMAT_RAW;
211 table[
"paf"] = SF_FORMAT_PAF;
212 table[
"svx"] = SF_FORMAT_SVX;
213 table[
"nist"] = SF_FORMAT_NIST;
214 table[
"voc"] = SF_FORMAT_VOC;
215 table[
"ircam"] = SF_FORMAT_IRCAM;
216 table[
"w64"] = SF_FORMAT_W64;
217 table[
"mat4"] = SF_FORMAT_MAT4;
218 table[
"mat5"] = SF_FORMAT_MAT5;
219 table[
"pvf"] = SF_FORMAT_PVF;
220 table[
"xi"] = SF_FORMAT_XI;
221 table[
"htk"] = SF_FORMAT_HTK;
222 table[
"sds"] = SF_FORMAT_SDS;
223 table[
"avr"] = SF_FORMAT_AVR;
224 table[
"wavex"] = SF_FORMAT_WAVEX;
225 table[
"sd2"] = SF_FORMAT_SD2;
226 table[
"flac"] = SF_FORMAT_FLAC;
227 table[
"caf"] = SF_FORMAT_CAF;
228 table[
"wve"] = SF_FORMAT_WVE;
229 table[
"ogg"] = SF_FORMAT_OGG;
230 table[
"mpc2k"] = SF_FORMAT_MPC2K;
231 table[
"rf64"] = SF_FORMAT_RF64;
236 std::map<std::string, int>::const_iterator it = table.find (ext);
238 return (it != table.end ()) ? it->second : 0;
278 #if defined (HAVE_SNDFILE)
280 int nargin = args.length ();
285 std::string filename = args(0).xstring_value (
"audiowrite: FILENAME must be a string");
290 if (args(1).is_uint8_type ())
291 bias =
scale = 127.5;
292 else if (args(1).is_int16_type ())
294 else if (args(1).is_int32_type ())
299 Matrix audio = args(1).matrix_value ();
301 if (! args(2).is_scalar_type () || ! args(2).isnumeric ())
302 error (
"audiowrite: sample rate FS must be a positive scalar integer");
303 int samplerate = args(2).int_value ();
305 error (
"audiowrite: sample rate FS must be a positive scalar integer");
308 std::size_t dotpos = filename.find_last_of (
'.');
309 if (dotpos != std::string::npos)
310 ext = filename.substr (dotpos + 1);
311 std::transform (ext.begin (), ext.end (), ext.begin (), ::tolower);
313 sf_count_t items_to_write = audio.
rows () * audio.
columns ();
315 if (audio.
rows () == 1)
321 for (
int i = 0; i < audio.
rows (); i++)
323 for (
int j = 0; j < audio.
columns (); j++)
332 memset (&info, 0,
sizeof (info));
334 sf_count_t chunk_size = 0;
338 info.format = SF_FORMAT_VORBIS;
344 chunk_size = 0x100000;
347 info.format = SF_FORMAT_PCM_16;
349 info.channels = audio.
columns ();
350 info.samplerate = samplerate;
351 info.format |= extension_to_format (ext);
353 std::string title =
"";
354 std::string artist =
"";
355 std::string comment =
"";
356 double quality = 0.75;
358 for (
int i = 3; i < nargin; i += 2)
361 error (
"audiowrite: invalid number of arguments");
363 std::string keyword_orig = args(i).string_value ();
364 std::string keyword = args(i).xtolower ().string_value ();
367 if (keyword ==
"bitspersample")
369 info.format &= ~SF_FORMAT_SUBMASK;
373 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
374 info.format |= SF_FORMAT_PCM_U8;
376 info.format |= SF_FORMAT_PCM_S8;
379 info.format |= SF_FORMAT_PCM_16;
382 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
383 info.format |= SF_FORMAT_PCM_32;
385 info.format |= SF_FORMAT_PCM_24;
389 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV
390 && args(1).isfloat ())
391 info.format |= SF_FORMAT_FLOAT;
393 info.format |= SF_FORMAT_PCM_32;
396 info.format |= SF_FORMAT_DOUBLE;
398 error (
"audiowrite: wrong number of bits specified");
400 else if (keyword ==
"bitrate")
402 "audiowrite: 'BitRate' accepted for Matlab "
403 "compatibility, but is ignored");
404 else if (keyword ==
"quality")
407 error (
"audiowrite: Quality value must be a scalar");
410 value_arg.
xdouble_value (
"audiowrite: Quality value must be a numeric scalar between 0 and 100");
412 if (
math::isnan (value) || value < 0 || value > 100)
413 error (
"audiowrite: Quality value must be a number between 0 and 100");
415 quality = value / 100;
417 else if (keyword ==
"title")
419 else if (keyword ==
"artist")
421 else if (keyword ==
"comment")
424 error (
"audiowrite: unrecognized option: '%s'", keyword_orig.c_str ());
427 SNDFILE *file = sf_open (filename.c_str (), SFM_WRITE, &info);
430 error (
"audiowrite: failed to open output file '%s': %s",
431 filename.c_str (), sf_strerror (file));
435 sf_command (file, SFC_SET_NORM_DOUBLE,
nullptr, SF_TRUE);
436 sf_command (file, SFC_SET_CLIPPING,
nullptr, SF_TRUE) ;
437 sf_command (file, SFC_SET_VBR_ENCODING_QUALITY, &quality,
sizeof (quality));
440 sf_set_string (file, SF_STR_TITLE, title.c_str ());
443 sf_set_string (file, SF_STR_ARTIST, artist.c_str ());
446 sf_set_string (file, SF_STR_COMMENT, comment.c_str ());
448 sf_count_t total_items_written = 0;
449 sf_count_t offset = 0;
452 chunk_size = items_to_write;
454 while (total_items_written < items_to_write)
456 if (items_to_write - offset < chunk_size)
457 chunk_size = items_to_write - offset;
459 sf_count_t items_written = sf_write_double (file, data+offset, chunk_size);
461 if (items_written != chunk_size)
462 error (
"audiowrite: write failed, wrote %" PRId64
" of %" PRId64
463 " items\n", items_written, chunk_size);
465 total_items_written += items_written;
466 offset += chunk_size;
476 octave_unused_parameter (args);
479 "reading and writing sound files through libsndfile");
617 #if defined (HAVE_SNDFILE)
619 if (args.length () != 1)
622 std::string filename = args(0).xstring_value (
"audioinfo: FILENAME must be a string");
624 sys::file_stat fs (filename);
626 error (
"audioinfo: FILENAME '%s' not found", filename.c_str ());
630 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
633 error (
"audioinfo: failed to open input file '%s': %s",
634 filename.c_str (), sf_strerror (file));
642 result.assign (
"Filename", full_name);
643 result.assign (
"CompressionMethod",
"");
644 result.assign (
"NumChannels", info.channels);
645 result.assign (
"SampleRate", info.samplerate);
647 if (info.frames != SF_COUNT_MAX)
648 dframes = info.frames;
651 result.assign (
"TotalSamples", dframes);
655 double drate = info.samplerate;
656 result.assign (
"Duration", dframes / drate);
659 result.assign (
"Duration", -1);
662 switch (info.format & SF_FORMAT_SUBMASK)
664 case SF_FORMAT_PCM_S8:
667 case SF_FORMAT_PCM_U8:
670 case SF_FORMAT_PCM_16:
673 case SF_FORMAT_PCM_24:
676 case SF_FORMAT_PCM_32:
679 case SF_FORMAT_FLOAT:
682 case SF_FORMAT_DOUBLE:
690 result.assign (
"BitsPerSample", bits);
691 result.assign (
"BitRate", -1);
692 result.assign (
"Title", sf_get_string (file, SF_STR_TITLE));
693 result.assign (
"Artist", sf_get_string (file, SF_STR_ARTIST));
694 result.assign (
"Comment", sf_get_string (file, SF_STR_COMMENT));
700 octave_unused_parameter (args);
703 "reading and writing sound files through libsndfile");
708 #if defined (HAVE_SNDFILE)
711 audio_sub_formats (
int format)
714 sf_command (
nullptr, SFC_GET_FORMAT_SUBTYPE_COUNT, &count,
sizeof (
int));
716 for (
int i = 0; i < count; i++)
720 sf_command (
nullptr, SFC_GET_FORMAT_SUBTYPE, &info,
sizeof (info));
723 memset (&sfinfo, 0,
sizeof (sfinfo));
725 sfinfo.format = (
format & SF_FORMAT_TYPEMASK) | info.format;
727 if (sf_format_check (&sfinfo))
745 #if defined (HAVE_SNDFILE)
747 if (args.length () > 1)
751 if (args.length () > 0)
753 search = args(0).string_value ();
758 sf_command (
nullptr, SFC_GET_FORMAT_MAJOR_COUNT, &count,
sizeof (
int));
760 for (
int i = 0; i < count; i++)
764 sf_command (
nullptr, SFC_GET_FORMAT_MAJOR, &info,
sizeof (info));
769 std::string nm = info.name;
777 octave_stdout <<
"extension: " << info.extension << std::endl;
781 audio_sub_formats (info.format);
789 octave_unused_parameter (args);
792 "getting sound formats through libsndfile");
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type columns(void) const
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type rows(void) const
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API T & xelem(octave_idx_type n)
Size of the specified dimension.
Matrix transpose(void) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type(void) const
std::string string_value(bool force=false) const
OCTINTERP_API double xdouble_value(const char *fmt,...) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
OCTINTERP_API void print_usage(void)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
void err_wrong_type_arg(const char *name, const char *s)
std::string canonicalize_file_name(const std::string &name)
void scale(Matrix &m, double x, double y, double z)
ColumnVector transform(const Matrix &m, double x, double y, double z)
intNDArray< octave_int16 > int16NDArray
intNDArray< octave_int32 > int32NDArray
intNDArray< octave_int8 > int8NDArray
static std::list< std::string > search(const std::string &path, const std::string &original_name, bool all)
class OCTAVE_API FloatNDArray
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
intNDArray< octave_uint8 > uint8NDArray
std::size_t format(std::ostream &os, const char *fmt,...)