46 safe_close (SNDFILE *file)
54 @deftypefn {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename})\n\
55 @deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{samples})\n\
57 @deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{datatype})\n\
58 @deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{samples}, @var{datatype})\n\
59 Read the audio file @var{filename} and return the audio data @var{y} and\n\
60 sampling rate @var{fs}.\n\
62 The audio data is stored as matrix with rows corresponding to audio frames\n\
63 and columns corresponding to channels.\n\
65 The optional two-element vector argument @var{samples} specifies starting\n\
68 The optional argument @var{datatype} specifies the datatype to return.\n\
69 If it is @qcode{\"native\"}, then the type of data depends on how the data\n\
70 is stored in the audio file.\n\
77 int nargin = args.
length ();
79 if (nargin < 1 || nargin > 3)
85 std::string filename = args(0).string_value ();
92 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
96 error (
"audioread: failed to open input file %s", filename.c_str ());
102 frame.
add_fcn (safe_close, file);
106 sf_read_float (file, data, info.frames * info.channels);
108 sf_count_t start = 0;
109 sf_count_t end = info.frames;
111 if ((nargin == 2 && ! args(1).is_string ()) || nargin == 3)
113 RowVector range = args(1).row_vector_value ();
118 if (range.
nelem () != 2)
120 error (
"audioread: invalid specification for range of frames");
124 double dstart =
xisinf (range(0)) ? info.frames : range(0);
125 double dend =
xisinf (range(1)) ? info.frames : range(1);
127 if (dstart < 1 || dstart > dend || dend > info.frames
130 error (
"audioread: invalid specification for range of frames");
138 sf_count_t items = end - start;
140 Matrix audio (items, info.channels);
144 data += start * info.channels;
146 for (
int i = 0; i < items; i++)
148 for (
int channel = 0; channel < info.channels; channel++)
149 paudio[items*channel+i] = *data++;
154 if ((nargin == 2 && args(1).is_string ()) || nargin == 3)
158 type = args(2).string_value ();
160 type = args(1).string_value ();
165 if (type ==
"native")
167 switch (info.format & SF_FORMAT_SUBMASK)
169 case SF_FORMAT_PCM_S8:
172 case SF_FORMAT_PCM_U8:
175 case SF_FORMAT_PCM_16:
178 case SF_FORMAT_PCM_24:
181 case SF_FORMAT_PCM_32:
195 retval(1) = info.samplerate;
196 retval(0) = ret_audio;
200 error (
"sndfile not found on your system and thus audioread is not functional");
210 extension_to_format (
const std::string& ext)
212 static bool initialized =
false;
214 static std::map<std::string, int> table;
218 table[
"wav"] = SF_FORMAT_WAV;
219 table[
"aiff"] = SF_FORMAT_AIFF;
220 table[
"au"] = SF_FORMAT_AU;
221 table[
"raw"] = SF_FORMAT_RAW;
222 table[
"paf"] = SF_FORMAT_PAF;
223 table[
"svx"] = SF_FORMAT_SVX;
224 table[
"nist"] = SF_FORMAT_NIST;
225 table[
"voc"] = SF_FORMAT_VOC;
226 table[
"ircam"] = SF_FORMAT_IRCAM;
227 table[
"w64"] = SF_FORMAT_W64;
228 table[
"mat4"] = SF_FORMAT_MAT4;
229 table[
"mat5"] = SF_FORMAT_MAT5;
230 table[
"pvf"] = SF_FORMAT_PVF;
231 table[
"xi"] = SF_FORMAT_XI;
232 table[
"htk"] = SF_FORMAT_HTK;
233 table[
"sds"] = SF_FORMAT_SDS;
234 table[
"avr"] = SF_FORMAT_AVR;
235 table[
"wavex"] = SF_FORMAT_WAVEX;
236 table[
"sd2"] = SF_FORMAT_SD2;
237 table[
"flac"] = SF_FORMAT_FLAC;
238 table[
"caf"] = SF_FORMAT_CAF;
239 table[
"wve"] = SF_FORMAT_WVE;
240 table[
"ogg"] = SF_FORMAT_OGG;
241 table[
"mpc2k"] = SF_FORMAT_MPC2K;
242 table[
"rf64"] = SF_FORMAT_RF64;
247 std::map<std::string, int>::const_iterator it = table.find (ext);
249 return (it != table.end ()) ? it->second : 0;
256 @deftypefn {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs})\n\
257 @deftypefnx {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs}, @var{name}, @var{value}, @dots{})\n\
259 Write audio data from the matrix @var{y} to @var{filename} at sampling rate\n\
260 @var{fs} with the file format determined by the file extension.\n\
262 Additional name/value argument pairs may be used to specify the\n\
263 following options:\n\
266 @item BitsPerSample\n\
267 Number of bits per sample, valid values are 8, 16, 24 and 32. Default is 16.\n\
270 Valid argument name, but ignored. Left for compatibility with @sc{matlab}.\n\
273 Quality setting for the Ogg Vorbis compressor. Values can range between 0\n\
274 and 100 with 100 being the highest quality setting. Default is 75.\n\
277 Title for the audio file.\n\
294 int nargin = args.
length ();
307 Matrix audio = args(1).matrix_value ();
315 if (args(1).is_uint8_type ())
317 else if (args(1).is_int16_type ())
319 else if (args(1).is_int32_type ())
321 else if (args(1).is_integer_type ())
333 size_t dotpos = filename.find_last_of (
".");
334 if (dotpos != std::string::npos)
335 ext = filename.substr (dotpos + 1);
336 std::transform (ext.begin (), ext.end (), ext.begin (), ::tolower);
338 sf_count_t items_to_write = audio.
rows () * audio.
columns ();
340 if (audio.
rows () == 1)
346 for (
int i = 0; i < audio.
rows (); i++)
348 for (
int j = 0; j < audio.
columns (); j++)
350 double elem = (audio.
xelem (i, j) - bias) / scale;
357 memset (&info, 0,
sizeof (info)) ;
359 sf_count_t chunk_size = 0;
363 info.format = SF_FORMAT_VORBIS;
369 chunk_size = 0x1FFFFE;
372 info.format = SF_FORMAT_PCM_16;
374 info.channels = audio.
columns ();
375 info.samplerate = samplerate;
376 info.channels = audio.
cols ();
377 info.format |= extension_to_format (ext);
379 std::string title =
"";
380 std::string artist =
"";
381 std::string comment =
"";
385 for (
int i = 3; i < nargin; i += 2)
387 if (args(i).string_value () ==
"BitsPerSample")
389 info.format &= ~SF_FORMAT_SUBMASK;
390 int bits = args(i + 1).int_value ();
393 if ((info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)
394 info.format |= SF_FORMAT_PCM_U8;
396 info.format |= SF_FORMAT_PCM_S8;
399 info.format |= SF_FORMAT_PCM_16;
401 info.format |= SF_FORMAT_PCM_24;
403 info.format |= SF_FORMAT_PCM_32;
406 error (
"audiowrite: wrong number of bits specified");
410 else if (args(i).string_value () ==
"BitRate")
416 else if (args(i).string_value () ==
"Title")
418 else if (args(i).string_value () ==
"Artist")
419 artist = args(i + 1).string_value ();
420 else if (args(i).string_value () ==
"Comment")
421 comment = args(i + 1).string_value ();
424 error (
"audiowrite: wrong argument name");
429 SNDFILE *file = sf_open (filename.c_str (), SFM_WRITE, &info);
433 error (
"audiowrite: failed to open output file %s", filename.c_str ());
439 frame.
add_fcn (safe_close, file);
442 sf_set_string (file, SF_STR_TITLE, title.c_str ());
445 sf_set_string (file, SF_STR_ARTIST, artist.c_str ());
448 sf_set_string (file, SF_STR_COMMENT, comment.c_str ());
450 sf_count_t total_items_written = 0;
451 sf_count_t offset = 0;
454 chunk_size = items_to_write;
456 while (total_items_written < items_to_write)
458 if (items_to_write - offset < chunk_size)
459 chunk_size = items_to_write - offset;
461 sf_count_t items_written = sf_write_float (file, data+offset, chunk_size);
463 if (items_written != chunk_size)
465 error (
"audiowrite: write failed, wrote %ld of %ld items\n",
466 items_written, chunk_size);
470 total_items_written += items_written;
471 offset += chunk_size;
476 error (
"sndfile not found on your system and thus audiowrite is not functional");
485 @deftypefn {Loadable Function} {@var{info} =} audioinfo (@var{filename})\n\
486 Return information about an audio file specified by @var{filename}.\n\
493 if (args.length () != 1)
506 SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
510 error (
"audioinfo: failed to open file %s", filename.c_str ());
516 frame.
add_fcn (safe_close, file);
520 result.
assign (
"Filename", filename);
521 result.
assign (
"CompressionMethod",
"");
522 result.
assign (
"NumChannels", info.channels);
523 result.
assign (
"SampleRate", info.samplerate);
524 result.
assign (
"TotalSamples", info.frames);
526 double dframes = info.frames;
527 double drate = info.samplerate;
528 result.
assign (
"Duration", dframes / drate);
531 switch (info.format & SF_FORMAT_SUBMASK)
533 case SF_FORMAT_PCM_S8:
536 case SF_FORMAT_PCM_U8:
539 case SF_FORMAT_PCM_16:
542 case SF_FORMAT_PCM_24:
545 case SF_FORMAT_PCM_32:
553 result.
assign (
"BitsPerSample", bits);
554 result.
assign (
"BitRate", -1);
555 result.
assign (
"Title", sf_get_string (file, SF_STR_TITLE));
556 result.
assign (
"Artist", sf_get_string (file, SF_STR_ARTIST));
557 result.
assign (
"Comment", sf_get_string (file, SF_STR_COMMENT));
563 error (
"sndfile not found on your system and thus audioinfo is not functional");
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
OCTINTERP_API void print_usage(void)
octave_idx_type length(void) const
intNDArray< octave_uint8 > uint8NDArray
int int_value(bool req_int=false, bool frc_str_conv=false) const
void error(const char *fmt,...)
intNDArray< octave_int16 > int16NDArray
octave_idx_type rows(void) const
octave_idx_type nelem(void) const
Number of elements in the array.
void add_fcn(void(*fcn)(void))
intNDArray< octave_int8 > int8NDArray
std::string string_value(bool force=false) const
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
Matrix transpose(void) const
octave_idx_type length(void) const
OCTAVE_API double D_NINT(double x)
T & xelem(octave_idx_type n)
charNDArray max(char d, const charNDArray &m)
intNDArray< octave_int32 > int32NDArray
void assign(const std::string &k, const octave_value &val)
void scale(Matrix &m, double x, double y, double z)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
ColumnVector transform(const Matrix &m, double x, double y, double z)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
const T * fortran_vec(void) const
octave_idx_type cols(void) const
octave_idx_type columns(void) const
charNDArray min(char d, const charNDArray &m)