OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::CleanupEncoder()
{
    // call terminate function of GSM AMR encoder
    AMREncodeExit(&iEncState, &iSidState);

    iEncState = NULL;
    iSidState = NULL;

    return GSMAMR_ENC_NO_ERROR;
}
status_t AMRNBEncoder::stop() {
    if (!mStarted) {
        LOGW("Call stop() when encoder has not started.");
        return OK;
    }

    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    delete mBufferGroup;
    mBufferGroup = NULL;

    mSource->stop();

    AMREncodeExit(&mEncState, &mSidState);
    mEncState = mSidState = NULL;

    mStarted = false;

    return OK;
}
int encode(int mode, const char *srcFile, const char *dstFile) {
    int           retVal     = EXIT_SUCCESS;
    FILE          *fSrc      = NULL;
    FILE          *fDst      = NULL;
    int           frameNum   = 0;
    bool          eofReached = false;
    uint16_t      *inputBuf  = NULL;
    uint8_t       *outputBuf = NULL;
    AmrNbEncState *amr       = NULL;

    clock_t   start, finish;
    double    duration = 0.0;

    // Open input file.
    fSrc = fopen(srcFile, "rb");
    if (fSrc == NULL) {
        fprintf(stderr, "Error opening input file\n");
        retVal = EXIT_FAILURE;
        goto safe_exit;
    }

    // Open output file.
    fDst = fopen(dstFile, "wb");
    if (fDst == NULL) {
        fprintf(stderr, "Error opening output file\n");
        retVal = EXIT_FAILURE;
        goto safe_exit;
    }

    // Allocate input buffer.
    inputBuf = (uint16_t*) malloc(kInputSize);
    assert(inputBuf != NULL);

    // Allocate output buffer.
    outputBuf = (uint8_t*) malloc(kOutputSize);
    assert(outputBuf != NULL);

    // Initialize encoder.
    amr = (AmrNbEncState*) malloc(sizeof(AmrNbEncState));
    AMREncodeInit(&amr->encCtx, &amr->pidSyncCtx, 0);

    // Write file header.
    fwrite("#!AMR\n", 1, 6, fDst);

    while (1) {
        // Read next input frame.
        int bytesRead;
        bytesRead = fread(inputBuf, 1, kInputSize, fSrc);
        if (bytesRead != kInputSize && !feof(fSrc)) {
            retVal = EXIT_FAILURE; // Invalid magic number.
            fprintf(stderr, "Error reading input file\n");
            goto safe_exit;
        } else if (feof(fSrc) && bytesRead == 0) {
            eofReached = true;
            break;
        }

        start = clock();

        // Encode the frame.
        Frame_Type_3GPP frame_type = (Frame_Type_3GPP) mode;
        int bytesGenerated;
        bytesGenerated = AMREncode(amr->encCtx, amr->pidSyncCtx, (Mode)mode,
                                   (Word16*)inputBuf, outputBuf, &frame_type,
                                   AMR_TX_WMF);

        // Convert from WMF to RFC 3267 format.
        if (bytesGenerated > 0) {
            outputBuf[0] = ((outputBuf[0] << 3) | 4) & 0x7c;
        }

        finish = clock();
        duration += finish - start;

        if (bytesGenerated < 0) {
            retVal = EXIT_FAILURE;
            fprintf(stderr, "Encoding error\n");
            goto safe_exit;
        }

        frameNum++;
        printf(" Frames processed: %d\n", frameNum);

        // Write the output.
        fwrite(outputBuf, 1, bytesGenerated, fDst);
    }

    // Dump the time taken by encode.
    printf("\n%2.5lf seconds\n", (double)duration/CLOCKS_PER_SEC);

safe_exit:

    // Free the encoder instance.
    if (amr) {
        AMREncodeExit(&amr->encCtx, &amr->pidSyncCtx);
        free(amr);
    }

    // Free input and output buffer.
    free(inputBuf);
    free(outputBuf);

    // Close the input and output files.
    if (fSrc) {
        fclose(fSrc);
    }
    if (fDst) {
        fclose(fDst);
    }

    return retVal;
}
void Encoder_Interface_exit(void* s) {
	struct encoder_state* state = (struct encoder_state*) s;
	AMREncodeExit(&state->encCtx, &state->pidSyncCtx);
	free(state);
}
SoftAMRNBEncoder::~SoftAMRNBEncoder() {
    if (mEncState != NULL) {
        AMREncodeExit(&mEncState, &mSidState);
        mEncState = mSidState = NULL;
    }
}