sndfile tweaks (add ul and al files and more record formats)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4211 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-02-12 22:42:22 +00:00
parent c133b3453d
commit 8e2c70d797
1 changed files with 66 additions and 16 deletions

View File

@ -34,6 +34,18 @@
static const char modname[] = "mod_sndfile"; static const char modname[] = "mod_sndfile";
static switch_memory_pool_t *module_pool = NULL;
static struct {
switch_hash_t *format_hash;
} globals;
struct format_map {
char *ext;
char *uext;
uint32_t format;
};
struct sndfile_context { struct sndfile_context {
SF_INFO sfinfo; SF_INFO sfinfo;
SNDFILE *handle; SNDFILE *handle;
@ -46,8 +58,9 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, char *pat
sndfile_context *context; sndfile_context *context;
int mode = 0; int mode = 0;
char *ext; char *ext;
int ready = 1; int ready = 0;
struct format_map *map = NULL;
if ((ext = strrchr(path, '.')) == 0) { if ((ext = strrchr(path, '.')) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n");
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
@ -72,9 +85,11 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, char *pat
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
map = switch_core_hash_find(globals.format_hash, ext);
if (mode & SFM_WRITE) { if (mode & SFM_WRITE) {
sf_count_t frames = 0 ; sf_count_t frames = 0 ;
context->sfinfo.channels = handle->channels; context->sfinfo.channels = handle->channels;
context->sfinfo.samplerate = handle->samplerate; context->sfinfo.samplerate = handle->samplerate;
if (handle->samplerate == 8000 || handle->samplerate == 16000) { if (handle->samplerate == 8000 || handle->samplerate == 16000) {
@ -85,20 +100,19 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, char *pat
context->sfinfo.format |= SF_FORMAT_PCM_32; context->sfinfo.format |= SF_FORMAT_PCM_32;
} }
sf_command (context->handle, SFC_FILE_TRUNCATE, &frames, sizeof (frames)) ; sf_command (context->handle, SFC_FILE_TRUNCATE, &frames, sizeof (frames));
/* Could add more else if() but i am too lazy atm.. */ if (map) {
if (!strcasecmp(ext, "wav")) { context->sfinfo.format |= map->format;
context->sfinfo.format |= SF_FORMAT_WAV; ready = 1;
} else {
ready = 0;
} }
} else { } else if (map) {
ready = 0; ready = 1;
} }
if (!ready) { if (!ready) {
ready = 1;
if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) { if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
context->sfinfo.channels = 1; context->sfinfo.channels = 1;
@ -119,16 +133,29 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, char *pat
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610; context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
context->sfinfo.channels = 1; context->sfinfo.channels = 1;
context->sfinfo.samplerate = 8000; context->sfinfo.samplerate = 8000;
} else if (!strcmp(ext, "ul")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
context->sfinfo.channels = 1;
context->sfinfo.samplerate = 8000;
} else if (!strcmp(ext, "al")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ALAW;
context->sfinfo.channels = 1;
context->sfinfo.samplerate = 8000;
} else {
ready = 0;
} }
} }
if (!ready) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path);
return SWITCH_STATUS_GENERR;
}
if ((mode & SFM_WRITE) && sf_format_check (&context->sfinfo) == 0) { if ((mode & SFM_WRITE) && sf_format_check (&context->sfinfo) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format);
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
}; };
if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) { if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path,
sf_strerror(context->handle)); sf_strerror(context->handle));
@ -272,7 +299,7 @@ static switch_status_t setup_formats(void)
char buffer[128]; char buffer[128];
int format, major_count, subtype_count, m, s; int format, major_count, subtype_count, m, s;
int len, x, skip; int len, x, skip;
char *extras[] = { "r8", "r16", "r24", "r32", "gsm", NULL }; char *extras[] = { "r8", "r16", "r24", "r32", "gsm", "ul", "al", NULL };
int exlen = (sizeof(extras) / sizeof(extras[0])); int exlen = (sizeof(extras) / sizeof(extras[0]));
buffer[0] = 0; buffer[0] = 0;
@ -306,11 +333,28 @@ static switch_status_t setup_formats(void)
} }
} }
if (!skip) { if (!skip) {
char *p;
struct format_map *map = switch_core_permanent_alloc(sizeof(*map));
if (!map) {
abort();
}
map->ext = switch_core_permanent_strdup(info.extension);
map->uext = switch_core_permanent_strdup(info.extension);
map->format = info.format;
for(p = map->ext; *p; p++) {
*p = tolower(*p);
}
for(p = map->uext; *p; p++) {
*p = toupper(*p);
}
switch_core_hash_insert(globals.format_hash, map->ext, map);
switch_core_hash_insert(globals.format_hash, map->uext, map);
supported_formats[len++] = (char *) info.extension; supported_formats[len++] = (char *) info.extension;
} }
format = info.format; format = info.format;
for (s = 0; s < subtype_count; s++) { for (s = 0; s < subtype_count; s++) {
info.format = s; info.format = s;
sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof(info)); sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof(info));
format = (format & SF_FORMAT_TYPEMASK) | info.format; format = (format & SF_FORMAT_TYPEMASK) | info.format;
@ -338,7 +382,13 @@ static switch_status_t setup_formats(void)
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
{ {
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
return SWITCH_STATUS_TERM;
}
switch_core_hash_init(&globals.format_hash, module_pool);
if (setup_formats() != SWITCH_STATUS_SUCCESS) { if (setup_formats() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }