📄 encode.c
字号:
/* block size */ if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); else if(xx!=0U) { flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx); return EncoderSession_finish_error(&encoder_session); } block_size= xx; /* skip any SSND offset bytes */ FLAC__ASSERT(offset<=LONG_MAX); if(!fskip_ahead(infile, offset)) { flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } if(data_bytes!=(sample_frames*bytes_per_frame)) { flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */ FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0); total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples; /* * now that we know the input size, canonicalize the * --until string to an absolute sample number: */ if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input)) return EncoderSession_finish_error(&encoder_session); encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples; FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0); if(encoder_session.skip>0U) { if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) { flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } } data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */ encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip; if(encoder_session.until > 0) { trim = total_samples_in_input - encoder_session.until; FLAC__ASSERT(total_samples_in_input > 0); FLAC__ASSERT(!options.common.sector_align); data_bytes-= (unsigned int)trim*bytes_per_frame; encoder_session.total_samples_to_encode-= trim; } if(options.common.sector_align) { align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U); if(options.common.is_last_file) encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */ else encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */ } /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */ encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54; if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate)) return EncoderSession_finish_error(&encoder_session); /* first do any samples in the reservoir */ if(options.common.sector_align && *options.common.align_reservoir_samples>0U) { if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) { print_error_with_state(&encoder_session, "ERROR during encoding"); return EncoderSession_finish_error(&encoder_session); } } /* decrement the data_bytes counter if we need to align the file */ if(options.common.sector_align) { if(options.common.is_last_file) *options.common.align_reservoir_samples= 0U; else { *options.common.align_reservoir_samples= align_remainder; data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame; } } /* now do from the file */ while(data_bytes>0) { size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile); if(bytes_read==0U) { if(ferror(infile)) { flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } else if(feof(infile)) { flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written); data_bytes= 0; } } else { if(bytes_read % bytes_per_frame != 0U) { flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } else { unsigned int frames= bytes_read/bytes_per_frame; format_input(input_, frames, true, false, channels, bps); if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) { print_error_with_state(&encoder_session, "ERROR during encoding"); return EncoderSession_finish_error(&encoder_session); } else data_bytes-= bytes_read; } } } if(trim>0) { FLAC__ASSERT(!options.common.sector_align); if(!fskip_ahead(infile, trim*bytes_per_frame)) { flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } } /* now read unaligned samples into reservoir or pad with zeroes if necessary */ if(options.common.sector_align) { if(options.common.is_last_file) { unsigned int pad_frames= 588U-align_remainder; if(pad_frames<588U) { unsigned int i; info_align_zero= pad_frames; for(i= 0U; i<channels; ++i) memset(input_[i], 0, pad_frames*(bps>>3)); if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) { print_error_with_state(&encoder_session, "ERROR during encoding"); return EncoderSession_finish_error(&encoder_session); } } } else { if(*options.common.align_reservoir_samples > 0) { size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile); FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U); if(bytes_read==0U && ferror(infile)) { flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) { flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written); } else { info_align_carry= *options.common.align_reservoir_samples; format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, true, false, channels, bps); } } } } if(pad==true) { unsigned char tmp; if(fread(&tmp, 1U, 1U, infile)<1U) { flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } } got_ssnd_chunk= true; } else { /* other chunk */ if(!strncmp(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)) { flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename); } else { flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id); } /* chunk size */ if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); else { unsigned long skip= xx+(xx & 1U); FLAC__ASSERT(skip<=LONG_MAX); if(!fskip_ahead(infile, skip)) { fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } } } } if(got_ssnd_chunk==false && sample_frames!=0U) { flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename); return EncoderSession_finish_error(&encoder_session); } return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);}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){ EncoderSession encoder_session; FLAC__bool is_unsigned_samples = false; unsigned channels = 0, bps = 0, sample_rate = 0, data_bytes; size_t bytes_per_wide_sample, bytes_read; FLAC__uint16 x; FLAC__uint32 xx; FLAC__bool got_fmt_chunk = false, got_data_chunk = false; unsigned align_remainder = 0; int info_align_carry = -1, info_align_zero = -1; (void)infilesize; (void)lookahead; (void)lookahead_length; if(! EncoderSession_construct( &encoder_session,#ifdef FLAC__HAS_OGG options.common.use_ogg,#else /*use_ogg=*/false,#endif options.common.verify, infile, infilename, outfilename ) ) return 1; /* * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks */ while(!feof(infile)) { if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(feof(infile)) break; if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */ unsigned block_align; /* fmt sub-chunk size */ if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(xx < 16) { flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx); return EncoderSession_finish_error(&encoder_session); } else if(xx != 16 && xx != 18) { flac__utils_printf(stderr, 1, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx); } data_bytes = xx; /* compression code */ if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(x != 1) { flac__utils_printf(stderr, 1, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x); return EncoderSession_finish_error(&encoder_session); } /* number of channels */ if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(x == 0 || x > FLAC__MAX_CHANNELS) { flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x); return EncoderSession_finish_error(&encoder_session); } else if(options.common.sector_align && x != 2) { flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x); return EncoderSession_finish_error(&encoder_session); } channels = x; /* sample rate */ if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(!FLAC__format_sample_rate_is_valid(xx)) { flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx); return EncoderSession_finish_error(&encoder_session); } else if(options.common.sector_align && xx != 44100) { flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned)xx); return EncoderSession_finish_error(&encoder_session); } sample_rate = xx; /* avg bytes per second (ignored) */ if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); /* block align */ if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); block_align = x; /* bits per sample */ if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename)) return EncoderSession_finish_error(&encoder_session); if(x != 8 && x != 16 && x != 24) { flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x); return EncoderSession_finish_error(&encoder_session); } else if(options.common.sector_align && x != 16) { flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -