Commit f12e23ed authored by ivo's avatar ivo

Support for linear 16 bit u-Law (.au) as source. Now you can do tricks with vsound. Closes #1105

svn path=/trunk/vorbis-tools/; revision=15308
parent 4cef1114
......@@ -18,6 +18,7 @@ vorbis-tools 1.2.1 -- Unreleased
* oggenc: support for 32 bit Wave files (#1326)
* oggenc: --ignorelength; support for Wave files > 4 GB (#1326)
* oggenc: split help text into manageable chunks to help translators (#1385)
* oggenc: support for linear 16 bit u-Law/.au (#1105)
* ogginfo: support for information in Kate streams (#1360)
* vcut: 64 bit fixes (#1366)
* vorbiscomment: correct memory allocation (#472)
......
......@@ -17,6 +17,7 @@
#include <string.h>
#include <sys/types.h>
#include <math.h>
#include <arpa/inet.h>
#include "audio.h"
#include "platform.h"
......@@ -53,6 +54,7 @@ input_format formats[] = {
{flac_id, 4, flac_open, flac_close, "flac", N_("FLAC file reader")},
{oggflac_id, 33, 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}
};
......@@ -324,7 +326,7 @@ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
(format.samplesize == 16 || format.samplesize == 8))
{
/* From here on, this is very similar to the wav code. Oh well. */
opt->rate = format.rate;
opt->channels = format.channels;
opt->read_samples = wav_read; /* Similar enough, so we use the same */
......@@ -360,7 +362,7 @@ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
int wav_id(unsigned char *buf, int len)
{
unsigned int flen;
if(len<12) return 0; /* Something screwed up */
if(memcmp(buf, "RIFF", 4))
......@@ -404,7 +406,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
if(len < 16)
{
fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
fprintf(stderr, _("Warning: Unrecognised format chunk in Wave header\n"));
return 0; /* Weird format chunk */
}
......@@ -417,12 +419,12 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
*/
if(len!=16 && len!=18 && len!=40)
fprintf(stderr,
_("Warning: INVALID format chunk in wav header.\n"
_("Warning: INVALID format chunk in Wave header.\n"
" Trying to read anyway (may not work)...\n"));
if(fread(buf,1,len,in) < len)
{
fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
fprintf(stderr, _("Warning: Unexpected EOF in reading Wave header\n"));
return 0;
}
......@@ -455,7 +457,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
else
{
fprintf(stderr,
_("ERROR: Wav file is unsupported type (must be standard PCM\n"
_("ERROR: Wave file is unsupported type (must be standard PCM\n"
" or type 3 floating point PCM)\n"));
return 0;
}
......@@ -823,6 +825,96 @@ void clear_scaler(oe_enc_opt *opt) {
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);
}
/* End Basic AU Support */
typedef struct {
audio_read_func real_reader;
void *real_readdata;
......@@ -846,10 +938,10 @@ void setup_downmix(oe_enc_opt *opt) {
downmix *d = calloc(1, sizeof(downmix));
if(opt->channels != 2) {
fprintf(stderr, "Internal error! Please report this bug.\n");
fprintf(stderr, _("Internal error! Please report this bug.\n"));
return;
}
d->bufs = malloc(2 * sizeof(float *));
d->bufs[0] = malloc(4096 * sizeof(float));
d->bufs[1] = malloc(4096 * sizeof(float));
......@@ -874,4 +966,3 @@ void clear_downmix(oe_enc_opt *opt) {
free(d->bufs);
free(d);
}
......@@ -5,6 +5,8 @@
#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);
......@@ -67,5 +69,22 @@ long wav_read(void *, float **buffer, int samples);
long wav_ieee_read(void *, float **buffer, int samples);
long raw_read_stereo(void *, float **buffer, int samples);
#endif /* __AUDIO_H */
/* AU code */
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
/* End AU code */
#endif /* __AUDIO_H */
......@@ -82,8 +82,8 @@ oggenc \- encode audio into the Ogg Vorbis format
.SH DESCRIPTION
.B oggenc
reads audio data in either raw, Wave, or AIFF format and encodes it into an
Ogg Vorbis stream.
reads audio data in either raw, Wave, AIFF or 16 bit u-Law (.au) format and
encodes it into an Ogg Vorbis stream.
.B oggenc
may also read audio data from FLAC and Ogg FLAC files depending upon compile-time options. If the input file "-" is specified, audio data is
read from
......
......@@ -494,11 +494,11 @@ static void usage(void)
"\n"));
fprintf(stdout, _(
"INPUT FILES:\n"
" OggEnc input files must currently be 24, 16, or 8 bit PCM WAV, AIFF, or AIFF/C\n"
" files, 32 bit IEEE floating point WAV, and optionally FLAC or Ogg FLAC. Files\n"
" OggEnc input files must currently be 24, 16, or 8 bit PCM Wave, 16 bit u-Law (.au), AIFF, or AIFF/C\n"
" files, 32 bit IEEE floating point Wave, and optionally FLAC or Ogg FLAC. Files\n"
" may be mono or stereo (or more channels) and any sample rate.\n"
" Alternatively, the --raw option may be used to use a raw PCM data file, which\n"
" must be 16 bit stereo little-endian PCM ('headerless wav'), unless additional\n"
" must be 16 bit stereo little-endian PCM ('headerless wave'), unless additional\n"
" parameters for raw mode are specified.\n"
" You can specify taking the file from stdin by using - as the input filename.\n"
" In this mode, output is to stdout unless an output filename is specified\n"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment