41 const
char *file_path,
46 char stream_name[128] =
"";
48 const char *spool_path = NULL;
60 if (!fh->samplerate) {
61 if (!(fh->samplerate = rate)) {
62 fh->samplerate = 8000;
66 if (
zstr(file_path)) {
74 fh->memory_pool =
pool;
85 fh->mm.samplerate = 44100;
91 fh->mm.try_hardware_encoder = 1;
93 if (*file_path ==
'{') {
115 if ((to = atoi(timeout)) < 1) {
127 fh->mm.samplerate = tmp;
133 if (tmp == 1 || tmp == 2) {
134 fh->mm.channels = tmp;
149 if (strrchr(val,
'k')) {
151 }
else if (strrchr(val,
'm')) {
177 float ftmp = atof(val);
186 if (strrchr(val,
'k')) {
188 }
else if (strrchr(val,
'm')) {
192 if (tmp > 0 && tmp < 104857600 ) {
200 if (!strcasecmp(val,
"slow")) {
202 }
else if (!strcasecmp(val,
"medium")) {
204 }
else if (!strcasecmp(val,
"fast")) {
212 if (!strcasecmp(val,
"baseline")) {
214 }
else if (!strcasecmp(val,
"main")) {
216 }
else if (!strcasecmp(val,
"high")) {
249 if ((ext = strrchr(file_path,
'.')) == 0) {
280 fh->spool_path = NULL;
290 fh->channels = channels;
295 file_path = fh->spool_path ? fh->spool_path : fh->file_path;
298 if (fh->spool_path) {
305 fh->real_channels = fh->channels;
308 fh->channels = channels;
313 fh->file_interface->file_close(fh);
319 fh->max_samples = (fh->samplerate / 1000) * to;
324 fh->native_rate = fh->samplerate;
326 fh->native_rate = rate;
329 if (fh->samplerate && rate && fh->samplerate != rate) {
331 if ((flags & SWITCH_FILE_FLAG_READ)) {
332 fh->samplerate = rate;
337 fh->pre_buffer_datalen = 0;
340 if (fh->pre_buffer_datalen) {
343 fh->pre_buffer_data =
switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen * fh->channels);
347 if (fh->real_channels != fh->channels && (flags & SWITCH_FILE_FLAG_READ) && !(fh->flags &
SWITCH_FILE_NOMUX)) {
386 if (fh->max_samples > 0 && fh->samples_in >= (
switch_size_t)fh->max_samples) {
392 *len =
switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
406 if (fh->pre_buffer) {
411 rlen = asis ? fh->pre_buffer_datalen : fh->pre_buffer_datalen / 2 / fh->real_channels;
414 if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) ==
SWITCH_STATUS_BREAK) {
422 fh->samples_in += rlen;
424 switch_mux_channels((int16_t *) fh->pre_buffer_data, rlen, fh->real_channels, fh->channels);
426 switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, asis ? rlen : rlen * 2 * fh->channels);
431 rlen =
switch_buffer_read(fh->pre_buffer, data, asis ? *len : *len * 2 * fh->channels);
432 *len = asis ? rlen : rlen / 2 / fh->channels;
452 fh->samples_in += *len;
460 if (!fh->resampler) {
470 if (fh->resampler->to_len < want || fh->resampler->to_len > orig_len) {
472 int factor = fh->resampler->to_len * fh->samplerate / 1000;
476 if (!fh->dbuf || fh->dbuflen < fh->resampler->to_len * 2 * fh->channels) {
478 fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
479 mem = realloc(fh->dbuf, fh->dbuflen);
483 switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
484 memcpy((int16_t *) fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
491 *len =
switch_buffer_read(fh->buffer, data, orig_len * 2 * fh->channels) / 2 / fh->channels;
493 memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
494 *len = fh->resampler->to_len;
519 if (!fh->file_interface->file_write) {
524 if (!fh->resampler) {
536 if (fh->resampler->to_len > orig_len) {
537 if (!fh->dbuf || (fh->dbuflen < fh->resampler->to_len * 2 * fh->channels)) {
539 fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
540 mem = realloc(fh->dbuf, fh->dbuflen);
544 switch_assert(fh->resampler->to_len * 2 * fh->channels <= fh->dbuflen);
545 memcpy(fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
548 memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
551 *len = fh->resampler->to_len;
558 if (fh->pre_buffer) {
567 if (rlen >= fh->pre_buffer_datalen) {
568 if ((blen =
switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
571 if (fh->channels > 1)
572 blen /= fh->channels;
573 if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) !=
SWITCH_STATUS_SUCCESS) {
578 fh->samples_out += orig_len;
583 fh->samples_out += orig_len;
598 if (!fh->file_interface->file_write_video) {
602 return fh->file_interface->file_write_video(fh, frame);
617 if (!fh->file_interface->file_read_video) {
621 status = fh->file_interface->file_read_video(fh, frame, flags);
655 if (fh->pre_buffer) {
660 unsigned int cur = 0;
663 fh->file_interface->file_seek(fh, &cur, fh->samples_out, SEEK_SET);
665 fh->file_interface->file_seek(fh, &cur, fh->offset_pos, SEEK_SET);
670 status = fh->file_interface->file_seek(fh, cur_pos, samples, whence);
672 fh->offset_pos = *cur_pos;
675 fh->samples_out = *cur_pos;
690 if (!fh->file_interface->file_set_string) {
694 return fh->file_interface->file_set_string(fh, col,
string);
706 if (!fh->file_interface->file_get_string) {
710 return fh->file_interface->file_get_string(fh, col,
string);
724 if (!fh->file_interface->file_truncate) {
732 if (fh->pre_buffer) {
756 if (fh->pre_buffer) {
764 if (fh->file_interface->file_command) {
766 status = fh->file_interface->file_command(fh, command);
785 if (fh->pre_buffer) {
791 if ((blen =
switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
794 if (fh->channels > 1)
795 blen /= fh->channels;
808 status = fh->file_interface->file_close(fh);
827 fh->memory_pool = NULL;
831 if (fh->spool_path) {
835 command =
switch_mprintf(
"move %s %s", fh->spool_path, fh->file_path);
837 command =
switch_mprintf(
"/bin/mv %s %s", fh->spool_path, fh->file_path);
839 if (system(command) == -1) {
848 fh->file_interface = NULL;
switch_status_t switch_core_file_set_string(switch_file_handle_t *fh, switch_audio_col_t col, const char *string)
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
switch_status_t switch_directory_exists(const char *dirname, switch_memory_pool_t *pool)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
#define SWITCH_CHANNEL_LOG
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
char * switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool)
switch_status_t switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup)
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
#define SWITCH_URL_SEPARATOR
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
switch_memory_pool_t * pool
#define SWITCH_AUDIO_SPOOL_PATH_VARIABLE
#define SWITCH_RESAMPLE_QUALITY
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
switch_status_t switch_core_file_seek(switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
#define UNPROTECT_INTERFACE(_it)
#define SWITCH_MUTEX_NESTED
#define SWITCH_PATH_SEPARATOR
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
switch_file_interface_t * switch_loadable_module_get_file_interface(const char *name, const char *modname)
Retrieve the file format interface by it's registered name.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
An abstraction of a data frame.
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
void switch_cond_next(void)
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
switch_status_t switch_file_exists(const char *filename, switch_memory_pool_t *pool)
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
switch_status_t switch_core_file_close(switch_file_handle_t *fh)
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
void switch_uuid_get(switch_uuid_t *uuid)
switch_status_t switch_core_file_get_string(switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
switch_status_t switch_core_perform_file_open(const char *file, const char *func, int line, switch_file_handle_t *fh, const char *file_path, uint32_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool)
#define switch_event_get_header(_e, _h)
switch_status_t switch_core_file_write_video(switch_file_handle_t *fh, switch_frame_t *frame)
switch_status_t switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len)
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_core_file_write(switch_file_handle_t *fh, void *data, switch_size_t *len)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
char * switch_core_sprintf(_In_ switch_memory_pool_t *pool, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the pool ...
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
#define SWITCH_UUID_FORMATTED_LENGTH
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.