Exemple #1
0
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;
}
Exemple #2
0
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;
}