+static pcm_io_vtbl_t pcm_io_vtbl = {
+ read_callback, seek_callback, tell_callback
+};
+static pcm_io_vtbl_t pcm_io_vtbl_noseek = { read_callback, 0, tell_callback };
+
+static
+pcm_reader_t *open_input(aacenc_param_ex_t *params)
+{
+ pcm_io_context_t io = { 0 };
+ pcm_reader_t *reader = 0;
+
+ if ((params->input_fp = aacenc_fopen(params->input_filename, "rb")) == 0) {
+ aacenc_fprintf(stderr, "ERROR: %s: %s\n", params->input_filename,
+ strerror(errno));
+ goto FAIL;
+ }
+ io.cookie = params->input_fp;
+ if (aacenc_seekable(params->input_fp))
+ io.vtbl = &pcm_io_vtbl;
+ else
+ io.vtbl = &pcm_io_vtbl_noseek;
+
+ if (params->is_raw) {
+ int bytes_per_channel;
+ pcm_sample_description_t desc = { 0 };
+ if (parse_raw_spec(params->raw_format, &desc) < 0) {
+ fprintf(stderr, "ERROR: invalid raw-format spec\n");
+ goto FAIL;
+ }
+ desc.sample_rate = params->raw_rate;
+ desc.channels_per_frame = params->raw_channels;
+ bytes_per_channel = (desc.bits_per_channel + 7) / 8;
+ desc.bytes_per_frame = params->raw_channels * bytes_per_channel;
+ if ((reader = raw_open(&io, &desc)) == 0) {
+ fprintf(stderr, "ERROR: failed to open raw input\n");
+ goto FAIL;
+ }
+ } else {
+ int c;
+ ungetc(c = getc(params->input_fp), params->input_fp);
+
+ switch (c) {
+ case 'R':
+ if ((reader = wav_open(&io, params->ignore_length)) == 0) {
+ fprintf(stderr, "ERROR: broken / unsupported input file\n");
+ goto FAIL;
+ }
+ break;
+ case 'c':
+ params->source_tag_ctx.add = aacenc_add_tag_entry_to_store;
+ params->source_tag_ctx.add_ctx = ¶ms->source_tags;
+ if ((reader = caf_open(&io,
+ aacenc_translate_generic_text_tag,
+ ¶ms->source_tag_ctx)) == 0) {
+ fprintf(stderr, "ERROR: broken / unsupported input file\n");
+ goto FAIL;
+ }
+ break;
+ default:
+ fprintf(stderr, "ERROR: unsupported input file\n");
+ goto FAIL;
+ }
+ }
+ reader = pcm_open_native_converter(reader);
+ if (reader && PCM_IS_FLOAT(pcm_get_format(reader)))
+ reader = limiter_open(reader);
+ if (reader && (reader = pcm_open_sint16_converter(reader)) != 0) {
+ if (do_smart_padding(params->profile))
+ reader = extrapolater_open(reader);
+ }
+ return reader;
+FAIL:
+ return 0;
+}
+