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