1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 18 #ifdef LINUX 19 #include <dlfcn.h> 20 #endif 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <time.h> 25 #include "voAMRWB.h" 26 #include "cmnMemory.h" 27 28 #define VOAMRWB_RFC3267_HEADER_INFO "#!AMR-WB\n" 29 30 #define INPUT_SIZE 640 31 #define OUTPUT_SIZE 1024 32 unsigned char InputBuf[INPUT_SIZE]; 33 unsigned char OutputBuf[OUTPUT_SIZE]; 34 35 void usage (void) { 36 printf ("AMR_WB Encoder HELP Displays this text\n"); 37 printf ("\n"); 38 printf ("Usage:\n"); 39 printf ("AMRWBEnc [options] Input_file output_file \n"); 40 printf ("\n"); 41 printf ("Options +M* +F* +DTX \n"); 42 printf ("Support \n"); 43 printf ("Options +M* for seting compression bitrate mode, default is 23.85kbps\n"); 44 printf (" +M0 = 6.6kbps \n"); 45 printf (" +M1 = 8.85kbps \n"); 46 printf (" +M2 = 12.65kbps \n"); 47 printf (" +M3 = 14.25kbps \n"); 48 printf (" +M4 = 15.58kbps \n"); 49 printf (" +M5 = 18.25kbps \n"); 50 printf (" +M6 = 19.85kbps \n"); 51 printf (" +M7 = 23.05kbps \n"); 52 printf (" +M8 = 23.85kbps \n"); 53 printf ("\n"); 54 printf ("Options +F* for setting output frame Type, default is RFC3267 \n"); 55 printf ("+F0 for AMR_WB Defualt bit extern short data frame type \n"); 56 printf ("+F1 for AMR_WB_ITU bit extern short data frame type \n"); 57 printf ("+F2 for RFC3267\n "); 58 printf ("\n"); 59 printf ("Options +DTX enable DTX mode, default is disable.\n"); 60 printf ("File names, input raw PCM data, and output is AMR_WB bit-stream file.\n"); 61 printf ("\n"); 62 } 63 64 int GetNextBuf(FILE* inFile,unsigned char* dst,int size) 65 { 66 int size2 = (int)fread(dst, sizeof(signed char), size,inFile); 67 return size2; 68 } 69 70 typedef int (VO_API * VOGETAUDIOENCAPI) (VO_AUDIO_CODECAPI * pEncHandle); 71 72 int encode( 73 int mode, 74 short allow_dtx, 75 VOAMRWBFRAMETYPE frameType, 76 const char* srcfile, 77 const char* dstfile 78 ) 79 { 80 int ret = 0; 81 int returnCode; 82 FILE *fsrc = NULL; 83 FILE *fdst = NULL; 84 int framenum = 0; 85 int eofFile = 0; 86 int size1 = 0; 87 int Relens; 88 89 VO_AUDIO_CODECAPI AudioAPI; 90 VO_MEM_OPERATOR moper; 91 VO_CODEC_INIT_USERDATA useData; 92 VO_HANDLE hCodec; 93 VO_CODECBUFFER inData; 94 VO_CODECBUFFER outData; 95 VO_AUDIO_OUTPUTINFO outFormat; 96 97 unsigned char *inBuf = InputBuf; 98 unsigned char *outBuf = OutputBuf; 99 100 101 #ifdef LINUX 102 void *handle = NULL; 103 void *pfunc; 104 VOGETAUDIOENCAPI pGetAPI; 105 #endif 106 107 clock_t start, finish; 108 double duration = 0.0; 109 110 if ((fsrc = fopen (srcfile, "rb")) == NULL) 111 { 112 ret = -1; 113 goto safe_exit; 114 } 115 116 if ((fdst = fopen (dstfile, "wb")) == NULL) 117 { 118 ret = -1; 119 goto safe_exit; 120 } 121 122 moper.Alloc = cmnMemAlloc; 123 moper.Copy = cmnMemCopy; 124 moper.Free = cmnMemFree; 125 moper.Set = cmnMemSet; 126 moper.Check = cmnMemCheck; 127 128 useData.memflag = VO_IMF_USERMEMOPERATOR; 129 useData.memData = (VO_PTR)(&moper); 130 131 #ifdef LINUX 132 handle = dlopen("/data/local/tmp/voAMRWBEnc.so", RTLD_NOW); 133 if(handle == 0) 134 { 135 printf("open dll error......"); 136 return -1; 137 } 138 139 pfunc = dlsym(handle, "voGetAMRWBEncAPI"); 140 if(pfunc == 0) 141 { 142 printf("open function error......"); 143 return -1; 144 } 145 146 pGetAPI = (VOGETAUDIOENCAPI)pfunc; 147 148 returnCode = pGetAPI(&AudioAPI); 149 if(returnCode) 150 { 151 printf("get APIs error......"); 152 return -1; 153 } 154 #else 155 ret = voGetAMRWBEncAPI(&AudioAPI); 156 if(ret) 157 { 158 ret = -1; 159 printf("get APIs error......"); 160 goto safe_exit; 161 } 162 #endif 163 164 //####################################### Init Encoding Section ######################################### 165 ret = AudioAPI.Init(&hCodec, VO_AUDIO_CodingAMRWB, &useData); 166 167 if(ret) 168 { 169 ret = -1; 170 printf("APIs init error......"); 171 goto safe_exit; 172 } 173 174 Relens = GetNextBuf(fsrc,InputBuf,INPUT_SIZE); 175 if(Relens!=INPUT_SIZE && !feof(fsrc)) 176 { 177 ret = -1; //Invalid magic number 178 printf("get next buffer error......"); 179 goto safe_exit; 180 } 181 182 //###################################### set encode Mode ################################################## 183 ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_FRAMETYPE, &frameType); 184 ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_MODE, &mode); 185 ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_DTX, &allow_dtx); 186 187 if(frameType == VOAMRWB_RFC3267) 188 { 189 /* write RFC3267 Header info to indicate single channel AMR file storage format */ 190 size1 = (int)strlen(VOAMRWB_RFC3267_HEADER_INFO); 191 memcpy(outBuf, VOAMRWB_RFC3267_HEADER_INFO, size1); 192 outBuf += size1; 193 } 194 195 //####################################### Encoding Section ######################################### 196 printf(" \n ---------------- Running -------------------------\n "); 197 198 do{ 199 inData.Buffer = (unsigned char *)inBuf; 200 inData.Length = Relens; 201 outData.Buffer = outBuf; 202 203 start = clock(); 204 205 /* decode one amr block */ 206 returnCode = AudioAPI.SetInputData(hCodec,&inData); 207 208 do { 209 returnCode = AudioAPI.GetOutputData(hCodec,&outData, &outFormat); 210 if(returnCode == 0) 211 { 212 framenum++; 213 printf(" Frames processed: %hd\r", framenum); 214 if(framenum == 1) 215 { 216 fwrite(OutputBuf, 1, outData.Length + size1, fdst); 217 fflush(fdst); 218 } 219 else 220 { 221 fwrite(outData.Buffer, 1, outData.Length, fdst); 222 fflush(fdst); 223 } 224 } 225 else if(returnCode == VO_ERR_LICENSE_ERROR) 226 { 227 printf("Encoder time reach upper limit......"); 228 goto safe_exit; 229 } 230 } while(returnCode != VO_ERR_INPUT_BUFFER_SMALL); 231 232 finish = clock(); 233 duration += finish - start; 234 235 if (!eofFile) { 236 Relens = GetNextBuf(fsrc, InputBuf, INPUT_SIZE); 237 inBuf = InputBuf; 238 if (feof(fsrc) && Relens == 0) 239 eofFile = 1; 240 } 241 } while (!eofFile && returnCode); 242 //####################################### End Encoding Section ######################################### 243 244 safe_exit: 245 returnCode = AudioAPI.Uninit(hCodec); 246 247 printf( "\n%2.5f seconds\n", (double)duration/CLOCKS_PER_SEC); 248 249 if (fsrc) 250 fclose(fsrc); 251 if (fdst) 252 fclose(fdst); 253 254 #ifdef LINUX 255 dlclose(handle); 256 #endif 257 258 return ret; 259 } 260 261 int main(int argc, char **argv) // for gcc compiler; 262 { 263 int mode, r; 264 int arg, filename=0; 265 char *inFileName = NULL; 266 char *outFileName = NULL; 267 short allow_dtx; 268 VOAMRWBFRAMETYPE frameType; 269 270 printf("\n"); 271 printf("************************Adaptive Multi-Rate Wide Band Encoder (AMR-WB)*******************************\n"); 272 printf("***********************************DEFINITIONS:*******************************************************\n"); 273 printf("AMR-WB encoder scheme is based on the principle of Algebraic Code Excited Linear Prediction algorithm\n"); 274 printf("The AMR-WB encoder compression MONO liner PCM speech input data at 16kHz sampling rate\n"); 275 printf("to one of nine data rate modes-6.60, 8.85, 12.65, 14.25, 15.85, 18.25, 19.25, 23.05 and 23.85kbps.\n"); 276 printf("The encoder supports output format AMRWB ITU, AMRWB RFC3267.\n"); 277 printf("\n"); 278 279 /*Encoder Default setting */ 280 mode = VOAMRWB_MD2385; 281 allow_dtx = 0; 282 frameType = VOAMRWB_RFC3267; 283 284 if(argc < 3){ 285 usage(); 286 return 0; 287 }else{ 288 for (arg = 1; arg < argc; arg++) { 289 if (argv [arg] [0] == '+') { 290 if(argv[arg][1] == 'M') 291 { 292 switch(argv[arg][2]) 293 { 294 case '0': mode = VOAMRWB_MD66; 295 break; 296 case '1': mode = VOAMRWB_MD885; 297 break; 298 case '2': mode = VOAMRWB_MD1265; 299 break; 300 case '3': mode = VOAMRWB_MD1425; 301 break; 302 case '4': mode = VOAMRWB_MD1585; 303 break; 304 case '5': mode = VOAMRWB_MD1825; 305 break; 306 case '6': mode = VOAMRWB_MD1985; 307 break; 308 case '7': mode = VOAMRWB_MD2305; 309 break; 310 case '8': mode = VOAMRWB_MD2385; 311 break; 312 default: 313 usage(); 314 printf ("Invalid parameter '%s'.\n", argv [arg]); 315 break; 316 } 317 }else if(argv[arg][1] == 'F') 318 { 319 switch(argv[arg][2]) 320 { 321 case '0': frameType = VOAMRWB_DEFAULT; 322 break; 323 case '1': frameType = VOAMRWB_ITU; 324 break; 325 case '2': frameType = VOAMRWB_RFC3267 ; 326 break; 327 default: 328 usage(); 329 printf ("Invalid parameter '%s'.\n", argv [arg]); 330 break; 331 332 333 } 334 }else if(strcmp (argv[arg], "+DTX") == 0) 335 { 336 allow_dtx = 1; 337 } 338 339 } else { 340 switch (filename) { 341 case 0: 342 inFileName = argv[arg]; 343 break; 344 case 1: 345 outFileName = argv[arg]; 346 break; 347 default: 348 usage (); 349 fprintf (stderr, "Invalid parameter '%s'.\n", argv [arg]); 350 return 0; 351 } 352 filename++; 353 } 354 } 355 } 356 357 r = encode(mode, allow_dtx, frameType, inFileName, outFileName); 358 if(r) 359 { 360 fprintf(stderr, "error: %d\n", r); 361 } 362 return r; 363 } 364 365