sox_bool sox_format_supports_encoding( char const * path, char const * filetype, sox_encodinginfo_t const * encoding) { #define enc_arg(T) (T)handler->write_formats[i++] sox_bool is_file_extension = filetype == NULL; sox_format_handler_t const * handler; unsigned i = 0, s; sox_encoding_t e; assert(path); assert(encoding); if (!filetype) filetype = lsx_find_file_extension(path); if (!filetype || !(handler = sox_find_format(filetype, is_file_extension)) || !handler->write_formats) return sox_false; while ((e = enc_arg(sox_encoding_t))) { if (e == encoding->encoding) { sox_bool has_bits; for (has_bits = sox_false; (s = enc_arg(unsigned)); has_bits = sox_true) if (s == encoding->bits_per_sample) return sox_true; if (!has_bits && !encoding->bits_per_sample) return sox_true; break; } while (enc_arg(unsigned)); }
bob::io::audio::Writer::Writer(const char* filename, double rate, sox_encoding_t encoding, size_t bits_per_sample): m_filename(filename), m_opened(false) { sox_signalinfo_t siginfo; siginfo.rate = rate; siginfo.precision = bits_per_sample; siginfo.channels = SOX_UNSPEC; #ifdef SOX_UNKNOWN_LEN siginfo.length = SOX_UNKNOWN_LEN; #else siginfo.length = -1; #endif const char* extension = lsx_find_file_extension(filename); if (bob::io::audio::SUPPORTED_FORMATS.find(extension-1) == bob::io::audio::SUPPORTED_FORMATS.end()) { //unsupported file format boost::format m("file `%s' cannot be written by SoX (file format `%d' is unsupported -- use `sox --help-format all' for a list of all supported formats"); m % filename % extension; throw std::runtime_error(m.str()); } sox_format_t* f = 0; if (encoding == SOX_ENCODING_UNKNOWN) { f = sox_open_write(filename, &siginfo, 0, extension, 0, 0); } else { sox_encodinginfo_t encoding_info; encoding_info.encoding = encoding; encoding_info.bits_per_sample = bits_per_sample; encoding_info.compression = HUGE_VAL; f = sox_open_write(filename, &siginfo, &encoding_info, 0, 0, 0); } if (!f) { boost::format m("file `%s' is not writeable by SoX (internal call to `sox_open_write()' failed) -- we suggest you check writing permissions and existence of leading paths"); m % filename; throw std::runtime_error(m.str()); } m_file = boost::shared_ptr<sox_format_t>(f, std::ptr_fun(bob::io::audio::close_sox_file)); m_typeinfo.dtype = bob::io::base::array::t_float64; m_typeinfo.nd = 2; m_typeinfo.shape[0] = 0; m_typeinfo.shape[1] = 0; m_typeinfo.update_strides(); m_buffer = boost::shared_array<sox_sample_t>(new sox_sample_t[m_typeinfo.shape[0]]); m_opened = true; ///< file is now considered opened for business }
sox_format_t * sox_open_read( char const * path, sox_signalinfo_t const * signal, sox_encodinginfo_t const * encoding, char const * filetype) { sox_format_t * ft = lsx_calloc(1, sizeof(*ft)); sox_format_handler_t const * handler; char const * const io_types[] = {"file", "pipe", "file URL"}; char const * type = ""; size_t input_bufsiz = sox_globals.input_bufsiz? sox_globals.input_bufsiz : sox_globals.bufsiz; if (filetype) { if (!(handler = sox_find_format(filetype, sox_false))) { lsx_fail("no handler for given file type `%s'", filetype); goto error; } ft->handler = *handler; } if (!(ft->handler.flags & SOX_FILE_NOSTDIO)) { if (!strcmp(path, "-")) { /* Use stdin if the filename is "-" */ if (sox_globals.stdin_in_use_by) { lsx_fail("`-' (stdin) already in use by `%s'", sox_globals.stdin_in_use_by); goto error; } sox_globals.stdin_in_use_by = "audio input"; SET_BINARY_MODE(stdin); ft->fp = stdin; } else { ft->fp = xfopen(path, "rb", &ft->io_type); type = io_types[ft->io_type]; if (ft->fp == NULL) { lsx_fail("can't open input %s `%s': %s", type, path, strerror(errno)); goto error; } } if (setvbuf (ft->fp, NULL, _IOFBF, sizeof(char) * input_bufsiz)) { lsx_fail("Can't set read buffer"); goto error; } ft->seekable = is_seekable(ft); } if (!filetype) { if (ft->seekable) { filetype = auto_detect_format(ft, lsx_find_file_extension(path)); lsx_rewind(ft); } #ifndef NO_REWIND_PIPE else if (!(ft->handler.flags & SOX_FILE_NOSTDIO) && input_bufsiz >= AUTO_DETECT_SIZE) { filetype = auto_detect_format(ft, lsx_find_file_extension(path)); rewind_pipe(ft->fp); ft->tell_off = 0; } #endif if (filetype) { lsx_report("detected file format type `%s'", filetype); if (!(handler = sox_find_format(filetype, sox_false))) { lsx_fail("no handler for detected file type `%s'", filetype); goto error; } } else { if (ft->io_type == lsx_io_pipe) { filetype = "sox"; /* With successful pipe rewind, this isn't useful */ lsx_report("assuming input pipe `%s' has file-type `sox'", path); } else if (!(filetype = lsx_find_file_extension(path))) { lsx_fail("can't determine type of %s `%s'", type, path); goto error; } if (!(handler = sox_find_format(filetype, sox_true))) { lsx_fail("no handler for file extension `%s'", filetype); goto error; } } ft->handler = *handler; if (ft->handler.flags & SOX_FILE_NOSTDIO) { xfclose(ft->fp, ft->io_type); ft->fp = NULL; } } if (!ft->handler.startread && !ft->handler.read) { lsx_fail("file type `%s' isn't readable", filetype); goto error; } ft->mode = 'r'; ft->filetype = lsx_strdup(filetype); ft->filename = lsx_strdup(path); if (signal) ft->signal = *signal; if (encoding) ft->encoding = *encoding; else sox_init_encodinginfo(&ft->encoding); set_endiannesses(ft); if ((ft->handler.flags & SOX_FILE_DEVICE) && !(ft->handler.flags & SOX_FILE_PHONY)) lsx_set_signal_defaults(ft); ft->priv = lsx_calloc(1, ft->handler.priv_size); /* Read and write starters can change their formats. */ if (ft->handler.startread && (*ft->handler.startread)(ft) != SOX_SUCCESS) { lsx_fail("can't open input %s `%s': %s", type, ft->filename, ft->sox_errstr); goto error; } /* Fill in some defaults: */ if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample)) ft->signal.precision = sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample); if (!(ft->handler.flags & SOX_FILE_PHONY) && !ft->signal.channels) ft->signal.channels = 1; if (sox_checkformat(ft) != SOX_SUCCESS) { lsx_fail("bad input format for %s `%s': %s", type, ft->filename, ft->sox_errstr); goto error; } if (signal) { if (signal->rate && signal->rate != ft->signal.rate) lsx_warn("can't set sample rate %g; using %g", signal->rate, ft->signal.rate); if (signal->channels && signal->channels != ft->signal.channels) lsx_warn("can't set %u channels; using %u", signal->channels, ft->signal.channels); } return ft; error: if (ft->fp && ft->fp != stdin) xfclose(ft->fp, ft->io_type); free(ft->priv); free(ft->filename); free(ft->filetype); free(ft); return NULL; }