summaryrefslogtreecommitdiff
path: root/amrwb/wrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'amrwb/wrapper.cpp')
-rw-r--r--amrwb/wrapper.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/amrwb/wrapper.cpp b/amrwb/wrapper.cpp
new file mode 100644
index 0000000..dd28281
--- /dev/null
+++ b/amrwb/wrapper.cpp
@@ -0,0 +1,128 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#include "dec_if.h"
+#include <stdlib.h>
+#include <string.h>
+#include <pvamrwbdecoder_api.h>
+#include <pvamrwbdecoder.h>
+#include <pvamrwbdecoder_cnst.h>
+#include <dtx.h>
+
+/* This is basically a C rewrite of decode_amr_wb.cpp */
+
+struct state {
+ void *st; /* State structure */
+ unsigned char *pt_st;
+ int16 *ScratchMem;
+
+ uint8* iInputBuf;
+ int16* iInputSampleBuf;
+ int16* iOutputBuf;
+
+ uint8 quality;
+ int16 mode;
+ int16 mode_old;
+ int16 frame_type;
+
+ int16 reset_flag;
+ int16 reset_flag_old;
+ int16 status;
+ RX_State rx_state;
+};
+
+void* D_IF_init(void) {
+ struct state* state = (struct state*) malloc(sizeof(struct state));
+ memset(state, 0, sizeof(*state));
+
+ state->iInputSampleBuf = (int16*) malloc(sizeof(int16)*KAMRWB_NB_BITS_MAX);
+ state->reset_flag = 0;
+ state->reset_flag_old = 1;
+ state->mode_old = 0;
+ state->rx_state.prev_ft = RX_SPEECH_GOOD;
+ state->rx_state.prev_mode = 0;
+ state->pt_st = (unsigned char*) malloc(pvDecoder_AmrWbMemRequirements());
+
+ pvDecoder_AmrWb_Init(&state->st, state->pt_st, &state->ScratchMem);
+ return state;
+}
+
+void D_IF_exit(void* s) {
+ struct state* state = (struct state*) s;
+ free(state->pt_st);
+ free(state->iInputSampleBuf);
+ free(state);
+}
+
+void D_IF_decode(void* s, const unsigned char* in, short* out, int bfi) {
+ struct state* state = (struct state*) s;
+
+ state->mode = (in[0] >> 3) & 0x0f;
+ in++;
+
+ state->quality = 1; /* ? */
+ mime_unsorting((uint8*) in, state->iInputSampleBuf, &state->frame_type, &state->mode, state->quality, &state->rx_state);
+
+ if ((state->frame_type == RX_NO_DATA) | (state->frame_type == RX_SPEECH_LOST)) {
+ state->mode = state->mode_old;
+ state->reset_flag = 0;
+ } else {
+ state->mode_old = state->mode;
+
+ /* if homed: check if this frame is another homing frame */
+ if (state->reset_flag_old == 1) {
+ /* only check until end of first subframe */
+ state->reset_flag = pvDecoder_AmrWb_homing_frame_test_first(state->iInputSampleBuf, state->mode);
+ }
+ }
+
+ /* produce encoder homing frame if homed & input=decoder homing frame */
+ if ((state->reset_flag != 0) && (state->reset_flag_old != 0)) {
+ /* set homing sequence ( no need to decode anything */
+
+ for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) {
+ out[i] = EHF_MASK;
+ }
+ } else {
+ int16 frameLength;
+ state->status = pvDecoder_AmrWb(state->mode,
+ state->iInputSampleBuf,
+ out,
+ &frameLength,
+ state->st,
+ state->frame_type,
+ state->ScratchMem);
+ }
+
+ for (int16 i = 0; i < AMR_WB_PCM_FRAME; i++) { /* Delete the 2 LSBs (14-bit output) */
+ out[i] &= 0xfffC;
+ }
+
+ /* if not homed: check whether current frame is a homing frame */
+ if (state->reset_flag_old == 0) {
+ /* check whole frame */
+ state->reset_flag = pvDecoder_AmrWb_homing_frame_test(state->iInputSampleBuf, state->mode);
+ }
+ /* reset decoder if current frame is a homing frame */
+ if (state->reset_flag != 0) {
+ pvDecoder_AmrWb_Reset(state->st, 1);
+ }
+ state->reset_flag_old = state->reset_flag;
+
+}
+