add support for encoding from non-compressed AIFF-C (SF bug #1090933: https://sourcef...
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 26 Aug 2005 05:57:04 +0000 (05:57 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 26 Aug 2005 05:57:04 +0000 (05:57 +0000)
doc/html/changelog.html
src/flac/encode.c
src/flac/encode.h
src/flac/main.c

index e90ae5c..3335a2d 100644 (file)
@@ -83,6 +83,7 @@
                        <li>
                                flac:
                                <ul>
+                                       <li>Add support for encoding from non-compressed AIFF-C (<a href="https://sourceforge.net/tracker/?func=detail&atid=113478&aid=1090933&group_id=13478">SF #1090933</a>).</li>
                                        <li>Importing of non-CDDA-compliant cuesheets now only issues a warning, not an error (see <a href="http://www.hydrogenaudio.org/forums/index.php?showtopic=31282">here</a>).</li>
                                        <li>Fixed a bug in cuesheet parsing where it would return an error if the last line of the cuesheet did not end with a newline.</li>
                                </ul>
index 38429ee..dd296a1 100644 (file)
@@ -160,9 +160,7 @@ static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
 /*
  * public routines
  */
-int
-flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename,
-       const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
+int flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options, FLAC__bool is_aifc)
 {
        EncoderSession encoder_session;
        FLAC__uint16 x;
@@ -170,6 +168,7 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
        unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
        FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
        int info_align_carry= -1, info_align_zero= -1;
+       FLAC__bool is_big_endian_pcm = true;
 
        (void)infilesize; /* silence compiler warning about unused parameter */
        (void)lookahead; /* silence compiler warning about unused parameter */
@@ -205,20 +204,21 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
                        return EncoderSession_finish_error(&encoder_session);
                }
 
-               if(got_comm_chunk==false && !strncmp(chunk_id, "COMM", 4)) { /* common chunk */
+               if(got_comm_chunk==false && !memcmp(chunk_id, "COMM", 4)) { /* common chunk */
                        unsigned long skip;
+                       const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
 
                        /* COMM chunk size */
                        if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
                                return EncoderSession_finish_error(&encoder_session);
-                       else if(xx<18U) {
-                               flac__utils_printf(stderr, 1, "%s: ERROR: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
+                       else if(xx<minimum_comm_size) {
+                               flac__utils_printf(stderr, 1, "%s: ERROR: non-standard %s 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx);
                                return EncoderSession_finish_error(&encoder_session);
                        }
-                       else if(xx!=18U) {
-                               flac__utils_printf(stderr, 1, "%s: WARNING: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
+                       else if(!is_aifc && xx!=minimum_comm_size) {
+                               flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size);
                        }
-                       skip= (xx-18U)+(xx & 1U);
+                       skip= (xx-minimum_comm_size)+(xx & 1U);
 
                        /* number of channels */
                        if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
@@ -264,6 +264,20 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
                        }
                        sample_rate= xx;
 
+                       /* check compression type for AIFF-C */
+                       if(is_aifc) {
+                               if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
+                                       return EncoderSession_finish_error(&encoder_session);
+                               if(xx == 0x736F7774) /* "sowt" */
+                                       is_big_endian_pcm = false;
+                               else if(xx == 0x4E4F4E45) /* "NONE" */
+                                       ; /* nothing to do, we already default to big-endian */
+                               else {
+                                       flac__utils_printf(stderr, 1, "%s: ERROR: can't handle AIFF-C compression type \"%c%c%c%c\"\n", encoder_session.inbasefilename, (char)(xx>>24), (char)((xx>>16)&8), (char)((xx>>8)&8), (char)(xx&8));
+                                       return EncoderSession_finish_error(&encoder_session);
+                               }
+                       }
+
                        /* skip any extra data in the COMM chunk */
                        if(!fskip_ahead(infile, skip)) {
                                flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
@@ -281,7 +295,7 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
 
                        got_comm_chunk= true;
                }
-               else if(got_ssnd_chunk==false && !strncmp(chunk_id, "SSND", 4)) { /* sound data chunk */
+               else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
                        unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
                        size_t bytes_per_frame= channels*(bps>>3);
                        FLAC__uint64 total_samples_in_input, trim = 0;
@@ -408,7 +422,7 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
                                        }
                                        else {
                                                unsigned int frames= bytes_read/bytes_per_frame;
-                                               format_input(input_, frames, true, false, channels, bps);
+                                               format_input(input_, frames, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
 
                                                if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
                                                        print_error_with_state(&encoder_session, "ERROR during encoding");
@@ -460,7 +474,7 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
                                                }
                                                else {
                                                        info_align_carry= *options.common.align_reservoir_samples;
-                                                       format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, true, false, channels, bps);
+                                                       format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
                                                }
                                        }
                                }
@@ -478,10 +492,10 @@ flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const ch
                        got_ssnd_chunk= true;
                }
                else { /* other chunk */
-                       if(!strncmp(chunk_id, "COMM", 4)) {
+                       if(!memcmp(chunk_id, "COMM", 4)) {
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
                        }
-                       else if(!strncmp(chunk_id, "SSND", 4)) {
+                       else if(!memcmp(chunk_id, "SSND", 4)) {
                                flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
                        }
                        else {
@@ -746,7 +760,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons
                                        }
                                        else {
                                                unsigned wide_samples = bytes_read / bytes_per_wide_sample;
-                                               format_input(input_, wide_samples, false, is_unsigned_samples, channels, bps);
+                                               format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
 
                                                if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
                                                        print_error_with_state(&encoder_session, "ERROR during encoding");
@@ -799,7 +813,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons
                                                }
                                                else {
                                                        info_align_carry = *options.common.align_reservoir_samples;
-                                                       format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, is_unsigned_samples, channels, bps);
+                                                       format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
                                                }
                                        }
                                }
index 9dd0300..773a154 100644 (file)
@@ -83,7 +83,7 @@ typedef struct {
        unsigned sample_rate;
 } raw_encode_options_t;
 
-int flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options);
+int flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options, FLAC__bool is_aifc);
 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options);
 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options);
 
index b27940d..fafd67d 100644 (file)
@@ -1239,7 +1239,8 @@ void show_explain()
        usage_header();
        usage_summary();
        printf("For encoding:\n");
-       printf("  The input file(s) may be a PCM RIFF WAVE file, AIFF file, or raw samples.\n");
+       printf("  The input file(s) may be a PCM RIFF WAVE file, AIFF (or uncompressed AIFF-C)\n");
+       printf("  file, or raw samples.\n");
        printf("  The output file(s) will be in native FLAC or Ogg FLAC format\n");
        printf("For decoding, the reverse is true.\n");
        printf("\n");
@@ -1475,7 +1476,8 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
        FILE *encode_infile;
        FLAC__byte lookahead[12];
        unsigned lookahead_length = 0;
-       FileFormat fmt= RAW;
+       FileFormat fmt = RAW;
+       FLAC__bool is_aifc = false;
        int retval;
        long infilesize;
        encode_options_t common_options;
@@ -1527,6 +1529,10 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                                fmt= WAV;
                        else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFF", 4))
                                fmt= AIF;
+                       else if(!strncmp((const char *)lookahead, "FORM", 4) && !strncmp((const char *)lookahead+8, "AIFC", 4)) {
+                               fmt= AIF;
+                               is_aifc = true;
+                       }
                        else {
                                if(fmt != RAW)
                                        format_mistake(infilename, fmt == AIF ? "AIFF" : "WAVE", "raw");
@@ -1626,7 +1632,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
                options.common = common_options;
 
                if(fmt == AIF)
-                       retval = flac__encode_aif(encode_infile, infilesize, infilename, outfilename, lookahead, lookahead_length, options);
+                       retval = flac__encode_aif(encode_infile, infilesize, infilename, outfilename, lookahead, lookahead_length, options, is_aifc);
                else
                        retval = flac__encode_wav(encode_infile, infilesize, infilename, outfilename, lookahead, lookahead_length, options);
        }