summaryrefslogtreecommitdiff
path: root/formats/format_au.c
diff options
context:
space:
mode:
Diffstat (limited to 'formats/format_au.c')
-rw-r--r--formats/format_au.c154
1 files changed, 37 insertions, 117 deletions
diff --git a/formats/format_au.c b/formats/format_au.c
index e8be324ae..06626a052 100644
--- a/formats/format_au.c
+++ b/formats/format_au.c
@@ -44,7 +44,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/module.h"
#include "asterisk/endian.h"
-#define BUF_SIZE 160
+#define BUF_SIZE 160 /* samples and 1 byte per sample */
#define AU_HEADER_SIZE 24
#define AU_HEADER(var) u_int32_t var[6]
@@ -58,26 +58,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define AU_ENC_8BIT_ULAW 1
-struct ast_filestream {
- void *reserved[AST_RESERVED_POINTERS];
- /* This is what a filestream means to us */
- FILE *f; /* Descriptor */
- struct ast_channel *owner;
- struct ast_frame fr; /* Frame information */
- char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
- char empty; /* Empty character */
- short buf[BUF_SIZE];
-};
-
-
-AST_MUTEX_DEFINE_STATIC(au_lock);
-static int localusecnt = 0;
-
-static char *name = "au";
-static char *desc = "Sun Microsystems AU format (signed linear)";
-static char *exts = "au";
-
-
#define AU_MAGIC 0x2e736e64
#if __BYTE_ORDER == __BIG_ENDIAN
#define htoll(b) (b)
@@ -130,7 +110,7 @@ static int check_header(FILE *f)
return -1;
}
sample_rate = ltohl(header[AU_HDR_SAMPLE_RATE_OFF]);
- if (sample_rate != 8000) {
+ if (sample_rate != DEFAULT_SAMPLE_RATE) {
ast_log(LOG_WARNING, "Sample rate can only be 8000 not %d\n", sample_rate);
return -1;
}
@@ -189,7 +169,7 @@ static int write_header(FILE *f)
header[AU_HDR_HDR_SIZE_OFF] = htoll(AU_HEADER_SIZE);
header[AU_HDR_DATA_SIZE_OFF] = 0;
header[AU_HDR_ENCODING_OFF] = htoll(AU_ENC_8BIT_ULAW);
- header[AU_HDR_SAMPLE_RATE_OFF] = htoll(8000);
+ header[AU_HDR_SAMPLE_RATE_OFF] = htoll(DEFAULT_SAMPLE_RATE);
header[AU_HDR_CHANNELS_OFF] = htoll(1);
/* Write an au header, ignoring sizes which will be filled in later */
@@ -201,97 +181,36 @@ static int write_header(FILE *f)
return 0;
}
-static struct ast_filestream *au_open(FILE *f)
-{
- struct ast_filestream *tmp;
-
- if (!(tmp = malloc(sizeof(struct ast_filestream)))) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return NULL;
- }
-
- memset(tmp, 0, sizeof(struct ast_filestream));
- if (check_header(f) < 0) {
- free(tmp);
- return NULL;
- }
- if (ast_mutex_lock(&au_lock)) {
- ast_log(LOG_WARNING, "Unable to lock au count\n");
- free(tmp);
- return NULL;
- }
- tmp->f = f;
- tmp->fr.data = tmp->buf;
- tmp->fr.frametype = AST_FRAME_VOICE;
- tmp->fr.subclass = AST_FORMAT_ULAW;
- /* datalen will vary for each frame */
- tmp->fr.src = name;
- tmp->fr.mallocd = 0;
- localusecnt++;
- ast_mutex_unlock(&au_lock);
- ast_update_use_count();
- return tmp;
-}
-
-static struct ast_filestream *au_rewrite(FILE *f, const char *comment)
+static int au_open(struct ast_filestream *s)
{
- struct ast_filestream *tmp;
-
- if ((tmp = malloc(sizeof(struct ast_filestream))) == NULL) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return NULL;
- }
-
- memset(tmp, 0, sizeof(struct ast_filestream));
- if (write_header(f)) {
- free(tmp);
- return NULL;
- }
- if (ast_mutex_lock(&au_lock)) {
- ast_log(LOG_WARNING, "Unable to lock au count\n");
- free(tmp);
- return NULL;
- }
- tmp->f = f;
- localusecnt++;
- ast_mutex_unlock(&au_lock);
- ast_update_use_count();
- return tmp;
+ if (check_header(s->f) < 0)
+ return -1;
+ return 0;
}
-static void au_close(struct ast_filestream *s)
+static int au_rewrite(struct ast_filestream *s, const char *comment)
{
- if (ast_mutex_lock(&au_lock)) {
- ast_log(LOG_WARNING, "Unable to lock au count\n");
- return;
- }
- localusecnt--;
- ast_mutex_unlock(&au_lock);
- ast_update_use_count();
- fclose(s->f);
- free(s);
+ if (write_header(s->f))
+ return -1;
+ return 0;
}
static struct ast_frame *au_read(struct ast_filestream *s, int *whennext)
{
int res;
- int delay;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass = AST_FORMAT_ULAW;
- s->fr.offset = AST_FRIENDLY_OFFSET;
s->fr.mallocd = 0;
- s->fr.data = s->buf;
- if ((res = fread(s->buf, 1, BUF_SIZE, s->f)) < 1) {
+ FR_SET_BUF(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
+ if ((res = fread(s->fr.data, 1, s->fr.datalen, s->f)) < 1) {
if (res)
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
return NULL;
}
- s->fr.samples = res;
+ *whennext = s->fr.samples = res;
s->fr.datalen = res;
- delay = s->fr.samples;
- *whennext = delay;
return &s->fr;
}
@@ -308,8 +227,8 @@ static int au_write(struct ast_filestream *fs, struct ast_frame *f)
return -1;
}
if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
- ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
- return -1;
+ ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
+ return -1;
}
update_header(fs->f);
return 0;
@@ -348,44 +267,45 @@ static int au_trunc(struct ast_filestream *fs)
static off_t au_tell(struct ast_filestream *fs)
{
- off_t offset;
-
- offset = ftello(fs->f);
+ off_t offset = ftello(fs->f);
return offset - AU_HEADER_SIZE;
}
-static char *au_getcomment(struct ast_filestream *s)
-{
- return NULL;
-}
+static struct ast_format_lock me = { .usecnt = -1 };
+
+static const struct ast_format au_f = {
+ .name = "au",
+ .exts = "au",
+ .format = AST_FORMAT_ULAW,
+ .open = au_open,
+ .rewrite = au_rewrite,
+ .write = au_write,
+ .seek = au_seek,
+ .trunc = au_trunc,
+ .tell = au_tell,
+ .read = au_read,
+ .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET, /* this many shorts */
+ .lockp = &me,
+};
int load_module()
{
- return ast_format_register(name, exts, AST_FORMAT_ULAW,
- au_open,
- au_rewrite,
- au_write,
- au_seek,
- au_trunc,
- au_tell,
- au_read,
- au_close,
- au_getcomment);
+ return ast_format_register(&au_f);
}
int unload_module()
{
- return ast_format_unregister(name);
+ return ast_format_unregister(au_f.name);
}
int usecount()
{
- return localusecnt;
+ return me.usecnt;
}
char *description()
{
- return desc;
+ return "Sun Microsystems AU format (signed linear)";
}
char *key()