26 #if defined (HAVE_CONFIG_H)
48 #if defined (HAVE_SNDFILE)
52 #if defined (HAVE_SNDFILE)
54 safe_close (SNDFILE *file)
82 #if defined (HAVE_SNDFILE)
84 int nargin = args.length ();
86 if (nargin < 1 || nargin > 3)
89 std::string filename = args(0).xstring_value (
"audioread: FILENAME must be a string");
93 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
96 error (
"audioread: failed to open input file '%s': %s",
97 filename.c_str (), sf_strerror (file));
101 frame.
add_fcn (safe_close, file);
105 sf_read_double (file, data, info.frames * info.channels);
107 sf_count_t start = 0;
108 sf_count_t end = info.frames;
110 if ((nargin == 2 && ! args(1).is_string ()) || nargin == 3)
112 RowVector range = args(1).row_vector_value ();
114 if (range.
numel () != 2)
115 error (
"audioread: invalid specification for range of frames");
120 if (dstart < 1 || dstart > dend || dend > info.frames
123 error (
"audioread: invalid specification for range of frames");
129 sf_count_t items = end - start;
131 Matrix audio (items, info.channels);
135 data += start * info.channels;
137 for (
int i = 0; i < items; i++)
139 for (
int channel = 0; channel < info.channels; channel++)
140 paudio[items*channel+i] = *data++;
145 if ((nargin == 2 && args(1).is_string ()) || nargin == 3)
149 type = args(2).string_value ();
151 type = args(1).string_value ();
153 if (
type ==
"native")
155 switch (info.format & SF_FORMAT_SUBMASK)
157 case SF_FORMAT_PCM_S8:
160 case SF_FORMAT_PCM_U8:
163 case SF_FORMAT_PCM_16:
166 case SF_FORMAT_PCM_24:
169 case SF_FORMAT_PCM_32:
172 case SF_FORMAT_FLOAT:
186 return ovl (ret_audio, info.samplerate);
190 octave_unused_parameter (args);
193 "reading and writing sound files through libsndfile");
198 #if defined (HAVE_SNDFILE)
201 extension_to_format (
const std::string& ext)
203 static bool initialized =
false;
205 static std::map<std::string, int> table;
209 table[
"wav"] = SF_FORMAT_WAV;
210 table[
"aiff"] = SF_FORMAT_AIFF;
211 table[
"au"] = SF_FORMAT_AU;
212 table[
"raw"] = SF_FORMAT_RAW;
213 table[
"paf"] = SF_FORMAT_PAF;
214 table[
"svx"] = SF_FORMAT_SVX;
215 table[
"nist"] = SF_FORMAT_NIST;
216 table[
"voc"] = SF_FORMAT_VOC;
217 table[
"ircam"] = SF_FORMAT_IRCAM;
218 table[
"w64"] = SF_FORMAT_W64;
219 table[
"mat4"] = SF_FORMAT_MAT4;
220 table[
"mat5"] = SF_FORMAT_MAT5;
221 table[
"pvf"] = SF_FORMAT_PVF;
222 table[
"xi"] = SF_FORMAT_XI;
223 table[
"htk"] = SF_FORMAT_HTK;
224 table[
"sds"] = SF_FORMAT_SDS;
225 table[
"avr"] = SF_FORMAT_AVR;
226 table[
"wavex"] = SF_FORMAT_WAVEX;
227 table[
"sd2"] = SF_FORMAT_SD2;
228 table[
"flac"] = SF_FORMAT_FLAC;
229 table[
"caf"] = SF_FORMAT_CAF;
230 table[
"wve"] = SF_FORMAT_WVE;
231 table[
"ogg"] = SF_FORMAT_OGG;
232 table[
"mpc2k"] = SF_FORMAT_MPC2K;
233 table[
"rf64"] = SF_FORMAT_RF64;
238 std::map<std::string, int>::const_iterator it = table.find (ext);
240 return (it != table.end ()) ? it->second : 0;
280 #if defined (HAVE_SNDFILE)
282 int nargin = args.length ();
287 std::string filename = args(0).xstring_value (
"audiowrite: FILENAME must be a string");
292 if (args(1).is_uint8_type ())
293 bias =
scale = 127.5;
294 else if (args(1).is_int16_type ())
296 else if (args(1).is_int32_type ())
301 Matrix audio = args(1).matrix_value ();
303 if (! args(2).is_scalar_type () || ! args(2).isnumeric ())
304 error (
"audiowrite: sample rate FS must be a positive scalar integer");
305 int samplerate = args(2).int_value ();
307 error (
"audiowrite: sample rate FS must be a positive scalar integer");
310 size_t dotpos = filename.find_last_of (
'.');
311 if (dotpos != std::string::npos)
312 ext = filename.substr (dotpos + 1);
313 std::transform (ext.begin (), ext.end (), ext.begin (), ::tolower);
315 sf_count_t items_to_write = audio.
rows () * audio.
columns ();
317 if (audio.
rows () == 1)
323 for (
int i = 0; i < audio.
rows (); i++)
325 for (
int j = 0; j < audio.
columns (); j++)
334 memset (&info, 0,
sizeof (info));
336 sf_count_t chunk_size = 0;
340 info.format = SF_FORMAT_VORBIS;
346 chunk_size = 0x100000;
349 info.format = SF_FORMAT_PCM_16;
351 info.channels = audio.
columns ();
352 info.samplerate = samplerate;
353 info.format |= extension_to_format (ext);
355 std::string title =
"";
356 std::string artist =
"";
357 std::string comment =
"";
358 double quality = 0.75;
360 for (
int i = 3; i < nargin; i += 2)
363 error (
"audiowrite: invalid number of arguments");
365 std::string keyword_orig = args(i).string_value ();
366 std::string keyword = args(i).xtolower ().string_value ();
369 if (keyword ==
"bitspersample")
371 info.format &= ~SF_FORMAT_SUBMASK;
375 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
376 info.format |= SF_FORMAT_PCM_U8;
378 info.format |= SF_FORMAT_PCM_S8;
381 info.format |= SF_FORMAT_PCM_16;
384 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
385 info.format |= SF_FORMAT_PCM_32;
387 info.format |= SF_FORMAT_PCM_24;
391 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV
392 && args(1).isfloat ())
393 info.format |= SF_FORMAT_FLOAT;
395 info.format |= SF_FORMAT_PCM_32;
398 info.format |= SF_FORMAT_DOUBLE;
400 error (
"audiowrite: wrong number of bits specified");
402 else if (keyword ==
"bitrate")
404 "audiowrite: 'BitRate' accepted for Matlab "
405 "compatibility, but is ignored");
406 else if (keyword ==
"quality")
409 error (
"audiowrite: Quality value must be a scalar");
411 double value = value_arg.
xdouble_value (
"audiowrite: Quality value must be a numeric scalar between 0 and 100");
414 error (
"audiowrite: Quality value must be a number between 0 and 100");
416 quality = value / 100;
418 else if (keyword ==
"title")
420 else if (keyword ==
"artist")
422 else if (keyword ==
"comment")
425 error (
"audiowrite: unrecognized option: '%s'", keyword_orig.c_str ());
428 SNDFILE *file = sf_open (filename.c_str (), SFM_WRITE, &info);
431 error (
"audiowrite: failed to open output file '%s': %s",
432 filename.c_str (), sf_strerror (file));
436 frame.
add_fcn (safe_close, file);
438 sf_command (file, SFC_SET_NORM_DOUBLE,
nullptr, SF_TRUE);
439 sf_command (file, SFC_SET_CLIPPING,
nullptr, SF_TRUE) ;
440 sf_command (file, SFC_SET_VBR_ENCODING_QUALITY, &quality,
sizeof (quality));
443 sf_set_string (file, SF_STR_TITLE, title.c_str ());
446 sf_set_string (file, SF_STR_ARTIST, artist.c_str ());
449 sf_set_string (file, SF_STR_COMMENT, comment.c_str ());
451 sf_count_t total_items_written = 0;
452 sf_count_t offset = 0;
455 chunk_size = items_to_write;
457 while (total_items_written < items_to_write)
459 if (items_to_write - offset < chunk_size)
460 chunk_size = items_to_write - offset;
462 sf_count_t items_written = sf_write_double (file, data+offset, chunk_size);
464 if (items_written != chunk_size)
465 error (
"audiowrite: write failed, wrote %" PRId64
" of %" PRId64
466 " items\n", items_written, chunk_size);
468 total_items_written += items_written;
469 offset += chunk_size;
478 octave_unused_parameter (args);
481 "reading and writing sound files through libsndfile");
610 #if defined (HAVE_SNDFILE)
612 if (args.length () != 1)
615 std::string filename = args(0).xstring_value (
"audioinfo: FILENAME must be a string");
619 error (
"audioinfo: FILENAME '%s' not found", filename.c_str ());
623 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
626 error (
"audioinfo: failed to open input file '%s': %s",
627 filename.c_str (), sf_strerror (file));
631 frame.
add_fcn (safe_close, file);
637 result.
assign (
"Filename", full_name);
638 result.
assign (
"CompressionMethod",
"");
639 result.
assign (
"NumChannels", info.channels);
640 result.
assign (
"SampleRate", info.samplerate);
641 result.
assign (
"TotalSamples", info.frames);
643 double dframes = info.frames;
644 double drate = info.samplerate;
645 result.
assign (
"Duration", dframes / drate);
648 switch (info.format & SF_FORMAT_SUBMASK)
650 case SF_FORMAT_PCM_S8:
653 case SF_FORMAT_PCM_U8:
656 case SF_FORMAT_PCM_16:
659 case SF_FORMAT_PCM_24:
662 case SF_FORMAT_PCM_32:
665 case SF_FORMAT_FLOAT:
668 case SF_FORMAT_DOUBLE:
676 result.
assign (
"BitsPerSample", bits);
677 result.
assign (
"BitRate", -1);
678 result.
assign (
"Title", sf_get_string (file, SF_STR_TITLE));
679 result.
assign (
"Artist", sf_get_string (file, SF_STR_ARTIST));
680 result.
assign (
"Comment", sf_get_string (file, SF_STR_COMMENT));
686 octave_unused_parameter (args);
689 "reading and writing sound files through libsndfile");
694 #if defined (HAVE_SNDFILE)
697 audio_sub_formats (
int format)
700 sf_command (
nullptr, SFC_GET_FORMAT_SUBTYPE_COUNT, &count,
sizeof (
int));
702 for (
int i = 0; i < count; i++)
706 sf_command (
nullptr, SFC_GET_FORMAT_SUBTYPE, &info,
sizeof (info));
709 memset (&sfinfo, 0,
sizeof (sfinfo));
711 sfinfo.format = (
format & SF_FORMAT_TYPEMASK) | info.format;
713 if (sf_format_check (&sfinfo))
731 #if defined (HAVE_SNDFILE)
733 if (args.length () > 1)
737 if (args.length () > 0)
739 search = args(0).string_value ();
744 sf_command (
nullptr, SFC_GET_FORMAT_MAJOR_COUNT, &count,
sizeof (
int));
746 for (
int i = 0; i < count; i++)
750 sf_command (
nullptr, SFC_GET_FORMAT_MAJOR, &info,
sizeof (info));
755 std::string nm = info.name;
763 octave_stdout <<
"extension: " << info.extension << std::endl;
767 audio_sub_formats (info.format);
773 octave_unused_parameter (args);
776 "getting sound formats through libsndfile");
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
octave_idx_type columns(void) const
T & xelem(octave_idx_type n)
Size of the specified dimension.
octave_idx_type numel(void) const
Number of elements in the array.
octave_idx_type rows(void) const
const T * fortran_vec(void) const
Size of the specified dimension.
Matrix transpose(void) const
void add_fcn(void(*fcn)(Params...), Args &&... args)
void assign(const std::string &k, const octave_value &val)
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type(void) const
double xdouble_value(const char *fmt,...) const
std::string string_value(bool force=false) const
#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)
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)
std::string canonicalize_file_name(const std::string &name)
size_t format(std::ostream &os, const char *fmt,...)
#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