1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <memory.h>
#include <ctype.h>
#include <jni.h>
#include <android/log.h>

extern "C" {
#include "g729/itu-g729/Headers/typedef.h" 
#include "g729/itu-g729/Headers/basic_op.h"
#include "g729/itu-g729/Headers/ld8a.h"
}

Word16 bad_lsf;
/*Variable initialization for encoder*/
extern Word16 *new_speech;     /* Pointer to new speech data            */
Word16 prm[PRM_SIZE];          /* Analysis parameters.                  */

/*Variable initialization for decoder*/
Word16  synth_buf[L_FRAME+M], *synth; /* Synthesis                   */
Word16  parm[PRM_SIZE+1];             /* Synthesis parameters        */
Word16  Az_dec[MP1*2];                /* Decoded Az for post-filter  */
Word16  T2[2];                        /* Pitch lag for 2 subframes   */
/*Common variable*/
Word16  i;

#define LOG_TAG "g729" // text for log tag

#undef DEBUG_G729

// the header length of the RTP frame (must skip when en/decoding)
#define  RTP_HDR_SIZE  12

#define  BITSTREAM_SIZE  10

static int codec_open = 0;

static JavaVM *gJavaVM;
const char *kInterfacePath = "org/sipdroid/pjlib/g729";


extern "C"
JNIEXPORT jint JNICALL Java_org_sipdroid_codecs_G729_open
  (JNIEnv *env, jobject obj) {
  int ret;

  if (codec_open++ != 0)
    return (jint)0;

  /*--------------------------------------------------------------------------*
   * Initialization of the encoder.                                             *
   *--------------------------------------------------------------------------*/

    Init_Pre_Process();
    Init_Coder_ld8a();
    Set_zero(prm, PRM_SIZE);

    /*-----------------------------------------------------------------*
     *           Initialization of decoder                             *
     *-----------------------------------------------------------------*/

      for (i=0; i<M; i++) synth_buf[i] = 0;
      synth = synth_buf + M;

      bad_lsf = 0;          /* Initialize bad LSF indicator */
      Init_Decod_ld8a();
      Init_Post_Filter();
      Init_Post_Process();

  return (jint)0;
}

extern "C"
JNIEXPORT jint JNICALL Java_org_sipdroid_codecs_G729_encode
    (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {

    Word16 serial[SERIAL_SIZE];    /* Output bitstream buffer               */
    jshort lin_input[L_FRAME];

    int i;

    int frsz=L_FRAME;
    unsigned int lin_pos = 0;

    if (!codec_open)
      return 0;

    for (i = 0; i < size; i+=frsz)
    {
      /*set lin pcm data into the lin_input array*/
      env->GetShortArrayRegion(lin, offset + i,frsz, lin_input);

      /*Return initialization for new_speech of input data*/
      memcpy(new_speech, (Word16 *)lin_input, sizeof(Word16)*L_FRAME);

      /*Preprocess start for new_speech data*/
      Pre_Process(new_speech, L_FRAME);

      Coder_ld8a(prm);

      prm2bits_ld8k( prm, serial);

      env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, BITSTREAM_SIZE, (jbyte *)serial);

      lin_pos += BITSTREAM_SIZE;
    }

    return (jint)lin_pos;
}

extern "C"
JNIEXPORT jint JNICALL Java_org_sipdroid_codecs_G729_decode
    (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {

    jbyte serial[SERIAL_SIZE];

    unsigned int lin_pos = L_FRAME;

    

    if (!codec_open)
      return 0;

    

      env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, serial);

      bits2prm_ld8k((Word16 *)&serial[2], &parm[1]);

        
        parm[0] = 0;           /* No frame erasure */
        for (i=2; i < SERIAL_SIZE; i++)
          if (serial[i] == 0 ) parm[0] = 1; 

        parm[4] = Check_Parity_Pitch(parm[3], parm[4]);

        Decod_ld8a(parm, synth, Az_dec, T2);

        Post_Filter(synth, Az_dec, T2);        /* Post-filter */

        Post_Process(synth, L_FRAME);

        env->SetShortArrayRegion(lin, 0, L_FRAME,synth);

        
    
  return (jint)lin_pos;
}


extern "C"
JNIEXPORT void JNICALL Java_org_sipdroid_codecs_G729_close
    (JNIEnv *env, jobject obj) {

  if (--codec_open != 0)
    return;


}