[PATCH] Preliminary AU file format support in oggenc
This file includes an initial implementation of the AU file format for the OGGENC program. This way, OGG files can be produced for the VSOUND virtual sound card driver.
diff -rc vorbis-tools-1.1.1/oggenc/audio.c vorbis-tools-1.1.1a/oggenc/audio.c
*** vorbis-tools-1.1.1/oggenc/audio.c 2005-06-13 15:11:44.000000000 +0200
--- vorbis-tools-1.1.1a/oggenc/audio.c 2006-11-27 13:01:01.000000000 +0100
***************
*** 14,19 ****
--- 14,20 ----
#include <string.h>
#include <sys/types.h>
#include <math.h>
+ #include <arpa/inet.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
***************
*** 51,56 ****
--- 52,58 ----
{flac_id, 4, flac_open, flac_close, "flac", N_("FLAC file reader")},
{oggflac_id, 32, flac_open, flac_close, "ogg", N_("Ogg FLAC file reader")},
#endif
+ {au_id, sizeof(auhdr),au_open,au_close, "au",N_("AU file reader") },
{NULL, 0, NULL, NULL, NULL, NULL}
};
***************
*** 801,803 ****
--- 803,892 ----
free(d);
}
+ // ------------- Basic AU support --------------
+
+
+ // 1=OK
+ // 0=KO
+ int au_id(unsigned char *buf, int len)
+ {
+ if (len < sizeof(auhdr))
+ return 0;
+ if (memcmp(buf,".snd",4))
+ return 0;
+ return 1;
+ }
+
+ typedef union {
+ int16_t signed16;
+ uint16_t unsigned16;
+ } sixteen_bit;
+
+ long au_read(void *in, float **buffer, int samples)
+ {
+ wavfile *wav = (wavfile *)in;
+ unsigned char *buf = alloca(samples*wav->channels*2);
+ long bytes_read = fread(buf, 1, samples*2*wav->channels, wav->f);
+ int i,j;
+ long realsamples;
+ uint16_t *sample;
+ sixteen_bit converter;
+
+ realsamples = bytes_read / (2 * wav->channels);
+
+ sample = (uint16_t *)buf;
+
+ for(i = 0; i < realsamples; i++)
+ {
+ for(j=0; j < wav->channels; j++)
+ {
+ converter.unsigned16 = ntohs(*sample++);
+ buffer[j][i] = converter.signed16 / 32768.0f;
+ }
+ }
+
+ return realsamples;
+ }
+
+ int au_open(FILE *in,
+ oe_enc_opt *opt,
+ unsigned char *buf, int buflen)
+ {
+ auhdr auHdr;
+ wavfile *wav = malloc(sizeof(wavfile));
+ int dataOffset;
+
+ if (NULL == wav) {
+ fprintf(stderr,"out of memory opening AU driver\n");
+ }
+
+ rewind(in);
+ fread(&auHdr,1,sizeof(auHdr),in);
+
+ if (SND_FORMAT_LINEAR_16 != ntohl(auHdr.formatCode)) {
+ fprintf(stderr,"At this moment, only linear 16 bit .au files are supported\n");
+ return 0;
+ }
+ dataOffset = ntohl(auHdr.dataOffset);
+ opt->rate = ntohl(auHdr.samplingRate);
+ opt->channels = ntohl(auHdr.numberChannels);
+ opt->read_samples = au_read;
+ opt->total_samples_per_channel = ntohl(auHdr.dataBytes) / (2 * opt->channels);
+ opt->readdata = wav;
+
+ wav->channels = opt->channels;
+ wav->samplesize = 4;
+ wav->totalsamples = opt->total_samples_per_channel;
+ wav->samplesread = 0;
+ wav->f = in;
+
+ // ignore: short bigendian;
+
+ fseek(in,dataOffset,SEEK_SET);
+ return 1;
+ }
+
+ void au_close(void *info)
+ {
+ free(info);
+ }
diff -rc vorbis-tools-1.1.1/oggenc/audio.h vorbis-tools-1.1.1a/oggenc/audio.h
*** vorbis-tools-1.1.1/oggenc/audio.h 2005-06-03 12:15:10.000000000 +0200
--- vorbis-tools-1.1.1a/oggenc/audio.h 2006-11-27 13:30:19.000000000 +0100
***************
*** 5,10 ****
--- 5,12 ----
#include "encode.h"
#include <stdio.h>
+ #include <arpa/inet.h>
+
int setup_resample(oe_enc_opt *opt);
void clear_resample(oe_enc_opt *opt);
void setup_downmix(oe_enc_opt *opt);
***************
*** 66,70 ****
--- 68,89 ----
long wav_ieee_read(void *, float **buffer, int samples);
long raw_read_stereo(void *, float **buffer, int samples);
+
+ int au_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen);
+ int au_id(unsigned char *buf, int len);
+ void au_close(void *);
+
+ typedef struct {
+ char magic[4];
+ uint32_t dataOffset;
+ uint32_t dataBytes;
+ uint32_t formatCode;
+ uint32_t samplingRate;
+ uint32_t numberChannels;
+ char optional[4];
+ } auhdr;
+
+ #define SND_FORMAT_LINEAR_16 3
+
#endif /* __AUDIO_H */