Commit df7476c4 authored by ivo's avatar ivo

Patches by Jose Antonio Peirote:

* fixed remapping channels bug
* support for WAVE_FORMAT_EXTENSIBLE headers
* support for 32 bit WAV files
* --ignorelength; support for WAV files > 4 GB
Closes #1326

svn path=/trunk/vorbis-tools/; revision=15003
parent c8fbdfa4
......@@ -7,6 +7,10 @@ vorbis-tools 1.2.1 -- Unreleased
* ogg123: return value to stop decoding after buffer is shut down (#1357)
* oggenc: fixed a core dump while resampling from FLAC (#1316)
* oggenc: fixed a typo in the Skeleton handling routine
* oggenc: fixed remapping channels bug (#1326)
* oggenc: support for WAVE_FORMAT_EXTENSIBLE headers (#1326)
* oggenc: support for 32 bit WAV files (#1326)
* oggenc: --ignorelength; support for WAV files > 4 GB (#1326)
* ogginfo: support for information in Kate streams (#1360)
* vcut: 64 bit fixes (#1366)
* vorbiscomment: correct memory allocation (#472)
......
......@@ -28,6 +28,9 @@
#endif
#define WAV_HEADER_SIZE 44
#define WAVE_FORMAT_PCM 0x0001
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
#define WAVE_FORMAT_EXTENSIBLE 0xfffe
/* Macros to read header data */
#define READ_U32_LE(buf) \
......@@ -377,8 +380,8 @@ static int wav_permute_matrix[6][6] =
{0,1},
{0,2,1},
{0,1,2,3},
{0,1,2,3,4}, /* No equivalent in wav? */
{0,2,1,5,3,4}
{0,2,1,3,4}, //{0,1,2,3,4}, /* No equivalent in wav? */
{0,2,1,4,5,3} //{0,2,1,5,3,4}
};
int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
......@@ -399,7 +402,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
if(!find_wav_chunk(in, "fmt ", &len))
return 0; /* EOF */
if(len < 16)
if(len < 16)
{
fprintf(stderr, _("Warning: Unrecognised format chunk in WAV header\n"));
return 0; /* Weird format chunk */
......@@ -410,13 +413,14 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
* it instead of refusing to work with the file. Please, if you
* have a program that's creating format chunks of sizes other than
* 16 or 18 bytes in size, report a bug to the author.
* (40 bytes accommodates WAVEFORMATEXTENSIBLE conforming files.)
*/
if(len!=16 && len!=18)
if(len!=16 && len!=18 && len!=40)
fprintf(stderr,
_("Warning: INVALID format chunk in wav header.\n"
" Trying to read anyway (may not work)...\n"));
if(fread(buf,1,16,in) < 16)
if(fread(buf,1,len,in) < len)
{
fprintf(stderr, _("Warning: Unexpected EOF in reading WAV header\n"));
return 0;
......@@ -424,8 +428,6 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
/* Deal with stupid broken apps. Don't use these programs.
*/
if(len - 16 > 0 && !seek_forward(in, len-16))
return 0;
format.format = READ_U16_LE(buf);
format.channels = READ_U16_LE(buf+2);
......@@ -434,15 +436,18 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
format.align = READ_U16_LE(buf+12);
format.samplesize = READ_U16_LE(buf+14);
if (format.format == WAVE_FORMAT_EXTENSIBLE && len > 25)
format.format = READ_U16_LE(buf+24);
if(!find_wav_chunk(in, "data", &len))
return 0; /* EOF */
if(format.format == 1)
if(format.format == WAVE_FORMAT_PCM)
{
samplesize = format.samplesize/8;
opt->read_samples = wav_read;
}
else if(format.format == 3)
else if(format.format == WAVE_FORMAT_IEEE_FLOAT)
{
samplesize = 4;
opt->read_samples = wav_ieee_read;
......@@ -466,8 +471,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
if(format.samplesize == samplesize*8 &&
(format.samplesize == 24 || format.samplesize == 16 ||
format.samplesize == 8 ||
(format.samplesize == 32 && format.format == 3)))
format.samplesize == 8 || format.samplesize == 32))
{
/* OK, good - we have the one supported format,
now we want to find the size of the file */
......@@ -481,29 +485,29 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
of trying to abstract stuff. */
wav->samplesize = format.samplesize;
if(len)
{
opt->total_samples_per_channel = len/(format.channels*samplesize);
}
else
{
long pos;
pos = ftell(in);
if(fseek(in, 0, SEEK_END) == -1)
opt->total_samples_per_channel = 0; /* Give up, like raw format */
if(!opt->ignorelength) { // if a new parameter NeroAacEnc style is included
if(len)
{
opt->total_samples_per_channel = 0; /* Give up */
opt->total_samples_per_channel = len/(format.channels*samplesize);
}
else
{
opt->total_samples_per_channel = (ftell(in) - pos)/
(format.channels*samplesize);
fseek(in,pos, SEEK_SET);
long pos;
pos = ftell(in);
if(fseek(in, 0, SEEK_END) != -1)
{
opt->total_samples_per_channel = (ftell(in) - pos)/
(format.channels*samplesize);
fseek(in,pos, SEEK_SET);
}
}
}
wav->totalsamples = opt->total_samples_per_channel;
opt->readdata = (void *)wav;
/* TODO: Read the extended wav header to get this right in weird cases,
* and/or error out if neccesary. Suck. */
wav->channel_permute = malloc(wav->channels * sizeof(int));
......@@ -521,7 +525,7 @@ int wav_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
else
{
fprintf(stderr,
_("ERROR: Wav file is unsupported subformat (must be 8,16, or 24 bit PCM\n"
_("ERROR: Wav file is unsupported subformat (must be 8,16,24 or 32 bit PCM\n"
"or floating point PCM)\n"));
return 0;
}
......@@ -543,8 +547,8 @@ long wav_read(void *in, float **buffer, int samples)
}
realsamples = bytes_read/(sampbyte*f->channels);
f->samplesread += realsamples;
if (f->totalsamples) f->samplesread += realsamples;
if(f->samplesize==8)
{
unsigned char *bufu = (unsigned char *)buf;
......@@ -602,6 +606,26 @@ long wav_read(void *in, float **buffer, int samples)
return 0;
}
}
else if (f->samplesize==32)
{
if (!f->bigendian)
{
for (i = 0; i < realsamples; i++)
{
for (j=0; j < f->channels; j++)
buffer[j][i] = ((buf[i*4*f->channels + 4*ch_permute[j] + 3] << 24) |
(((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j] + 2] << 16) |
(((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j] + 1] << 8) |
(((unsigned char *)buf)[i*4*f->channels + 4*ch_permute[j]] & 0xff))
/ 2147483648.0f;
}
}
else {
fprintf(stderr, _("Big endian 32 bit PCM data is not currently "
"supported, aborting.\n"));
return 0;
}
}
else {
fprintf(stderr, _("Internal error: attempt to read unsupported "
"bitdepth %d\n"), f->samplesize);
......
......@@ -89,6 +89,7 @@ typedef struct
unsigned int serial;
unsigned int skeleton_serial;
int fixedserial;
int ignorelength;
} oe_options;
typedef struct
......@@ -127,6 +128,7 @@ typedef struct
FILE *out;
char *filename;
char *infilename;
int ignorelength;
} oe_enc_opt;
......
......@@ -63,9 +63,10 @@ struct option long_options[] = {
{"managed", 0, 0, 0},
{"resample",1,0,0},
{"downmix", 0,0,0},
{"scale", 1, 0, 0},
{"scale", 1, 0, 0},
{"advanced-encode-option", 1, 0, 0},
{"discard-comments", 0, 0, 0},
{"ignorelength", 0, 0, 0},
{NULL,0,0,0}
};
......@@ -84,7 +85,7 @@ int main(int argc, char **argv)
oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NULL, 0, NULL, 0, NULL, 0, 1, 0, 0, 0,16,44100,2, 0, NULL,
DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE,
NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0};
NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0, 0};
int i;
......@@ -160,6 +161,7 @@ int main(int argc, char **argv)
enc_opts.comments = &vc;
enc_opts.copy_comments = opt.copy_comments;
enc_opts.with_skeleton = opt.with_skeleton;
enc_opts.ignorelength = opt.ignorelength;
/* OK, let's build the vorbis_comments structure */
build_comments(&vc, &opt, i, &artist, &album, &title, &track,
......@@ -446,6 +448,8 @@ static void usage(void)
" stream after the first.\n"
" --discard-comments Prevents comments in FLAC and Ogg FLAC files from\n"
" being copied to the output Ogg Vorbis file.\n"
" --ignorelength Ignore the datalength in wav headers. This will allow\n"
" support for files > 4GB and STDIN data streams. \n"
"\n"
" Naming:\n"
" -o, --output=fn Write file to fn (only valid in single-file mode)\n"
......@@ -670,8 +674,11 @@ static void parse_options(int argc, char **argv, oe_options *opt)
opt->advopt[opt->advopt_count - 1].val = val;
}
else if(!strcmp(long_options[option_index].name, "discard-comments")) {
opt->copy_comments = 0;
}
opt->copy_comments = 0;
}
else if(!strcmp(long_options[option_index].name, "ignorelength")) {
opt->ignorelength = 1;
}
else {
fprintf(stderr, _("Internal error parsing command line options\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