static int encode(aacenc_param_ex_t *params, pcm_reader_t *reader, HANDLE_AACENCODER encoder, uint32_t frame_length, m4af_ctx_t *m4af) { int16_t *ibuf = 0, *ip; aacenc_frame_t obuf[2] = {{ 0 }}, *obp; unsigned flip = 0; int nread = 1; int rc = -1; int remaining, consumed; int frames_written = 0, encoded = 0; aacenc_progress_t progress = { 0 }; const pcm_sample_description_t *fmt = pcm_get_format(reader); ibuf = malloc(frame_length * fmt->bytes_per_frame); aacenc_progress_init(&progress, pcm_get_length(reader), fmt->sample_rate); for (;;) { /* * Since we delay the write, we cannot just exit loop when interrupted. * Instead, we regard it as EOF. */ if (g_interrupted) nread = 0; if (nread > 0) { if ((nread = pcm_read_frames(reader, ibuf, frame_length)) < 0) { fprintf(stderr, "ERROR: read failed\n"); goto END; } if (!params->silent) aacenc_progress_update(&progress, pcm_get_position(reader), fmt->sample_rate * 2); } ip = ibuf; remaining = nread; do { obp = &obuf[flip]; consumed = aac_encode_frame(encoder, fmt, ip, remaining, obp); if (consumed < 0) goto END; if (consumed == 0 && obp->size == 0) goto DONE; if (obp->size == 0) break; remaining -= consumed; ip += consumed * fmt->channels_per_frame; flip ^= 1; /* * As we pad 1 frame at beginning and ending by our extrapolator, * we want to drop them. * We delay output by 1 frame by double buffering, and discard * second frame and final frame from the encoder. * Since sbr_header is included in the first frame (in case of * SBR), we cannot discard first frame. So we pick second instead. */ ++encoded; if (encoded == 1 || encoded == 3) continue; obp = &obuf[flip]; if (write_sample(params->output_fp, m4af, obp) < 0) goto END; ++frames_written; } while (remaining > 0); } DONE: if (!params->silent) aacenc_progress_finish(&progress, pcm_get_position(reader)); rc = frames_written; END: if (ibuf) free(ibuf); if (obuf[0].data) free(obuf[0].data); if (obuf[1].data) free(obuf[1].data); return rc; }
static int encode_sndfile(SNDFILE* snd, SF_INFO* info, pcm_sample_description_t* format, HANDLE_AACENCODER encoder, uint32_t frame_length, FILE *ofp, m4af_ctx_t *m4af, int show_progress) { #ifdef USE_LIBSAMPLERATE //short *resamplebuf = 0; SRC_STATE* srcstate = NULL; SRC_DATA srcdata; int srcerror = 0; float *ibuf = 0; #else short *ibuf = 0; #endif int16_t *pcmbuf = 0; uint32_t pcmsize = 0; uint8_t *obuf = 0; uint32_t olen; uint32_t osize = 0; int nread = 1; int consumed, written; int rc = -1; int frames_written = 0; aacenc_progress_t progress = { 0 }; ibuf = malloc(frame_length * format->bytes_per_frame); #ifdef USE_LIBSAMPLERATE if(format->sample_rate != info->samplerate) { /* set up resampler */ srcstate = src_new(SRC_SINC_MEDIUM_QUALITY, info->channels, &srcerror); srcdata.src_ratio = format->sample_rate; srcdata.src_ratio /= info->samplerate; srcdata.data_in = ibuf; srcdata.data_out = malloc(frame_length * format->bytes_per_frame * srcdata.src_ratio); srcdata.end_of_input = 0; } #endif aacenc_progress_init(&progress, info->frames, info->samplerate); do { if (g_interrupted) nread = 0; else if (nread) { #ifdef USE_LIBSAMPLERATE if ((nread = sf_readf_float(snd, ibuf, frame_length)) < 0) { #else if ((nread = sf_readf_short(snd, ibuf, frame_length)) < 0) { #endif fprintf(stderr, "ERROR: read failed\n"); goto END; } else if (nread > 0) { float* in_buf = ibuf; #ifdef USE_LIBSAMPLERATE if(srcstate) { /* run converstion */ srcdata.input_frames = nread; srcdata.output_frames = frame_length; if(srcerror = src_process(srcstate, &srcdata)) { fprintf(stderr, "resample error: %s\n", src_strerror(srcerror)); goto END; } //printf("resampled %d samples to %d samples\n", srcdata.input_frames_used, srcdata.output_frames_gen); in_buf = srcdata.data_out; nread = srcdata.output_frames_gen; } #endif if (pcm_convert_to_native_sint16(format, in_buf, nread, &pcmbuf, &pcmsize) < 0) { fprintf(stderr, "ERROR: unsupported sample format\n"); goto END; } } if (show_progress) aacenc_progress_update(&progress, sf_seek(snd, 0, SEEK_CUR), info->samplerate * 2); } written = nread; do { if ((consumed = aac_encode_frame(encoder, format, pcmbuf + (nread-written)*info->channels, written, &obuf, &olen, &osize)) < 0) goto END; //printf("nread: %d consumed: %d olen: %d\n", nread, consumed, olen); written -= (consumed / info->channels); if (olen > 0) { if (write_sample(ofp, m4af, obuf, olen, frame_length) < 0) goto END; ++frames_written; //printf("wrote frame %d\n", frames_written); } } while (written > 0); } while (nread > 0 || olen > 0); if (show_progress) aacenc_progress_finish(&progress, sf_seek(snd, 0, SEEK_CUR)); rc = frames_written; END: if (ibuf) free(ibuf); if (pcmbuf) free(pcmbuf); if (obuf) free(obuf); #ifdef USE_SAMPLERATE if (srcstate) { free(srcdata.data_out); src_delete(srcstate); } #endif return rc; } #endif static int encode(wav_reader_t *wavf, HANDLE_AACENCODER encoder, uint32_t frame_length, FILE *ofp, m4af_ctx_t *m4af, int show_progress) { uint8_t *ibuf = 0; int16_t *pcmbuf = 0; uint32_t pcmsize = 0; uint8_t *obuf = 0; uint32_t olen; uint32_t osize = 0; int nread = 1; int consumed; int rc = -1; int frames_written = 0; aacenc_progress_t progress = { 0 }; const pcm_sample_description_t *format = wav_get_format(wavf); ibuf = malloc(frame_length * format->bytes_per_frame); aacenc_progress_init(&progress, wav_get_length(wavf), format->sample_rate); do { if (g_interrupted) nread = 0; else if (nread) { if ((nread = wav_read_frames(wavf, ibuf, frame_length)) < 0) { fprintf(stderr, "ERROR: read failed\n"); goto END; } else if (nread > 0) { if (pcm_convert_to_native_sint16(format, ibuf, nread, &pcmbuf, &pcmsize) < 0) { fprintf(stderr, "ERROR: unsupported sample format\n"); goto END; } } if (show_progress) aacenc_progress_update(&progress, wav_get_position(wavf), format->sample_rate * 2); } if ((consumed = aac_encode_frame(encoder, format, pcmbuf, nread, &obuf, &olen, &osize)) < 0) goto END; if (olen > 0) { if (write_sample(ofp, m4af, obuf, olen, frame_length) < 0) goto END; ++frames_written; } } while (nread > 0 || olen > 0); if (show_progress) aacenc_progress_finish(&progress, wav_get_position(wavf)); rc = frames_written; END: if (ibuf) free(ibuf); if (pcmbuf) free(pcmbuf); if (obuf) free(obuf); return rc; }