/* | |
** Copyright 2003-2010, VisualOn, Inc. | |
** | |
** 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. | |
*/ | |
#ifdef LINUX | |
#include <dlfcn.h> | |
#endif | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include "voAMRWB.h" | |
#include "cmnMemory.h" | |
#define VOAMRWB_RFC3267_HEADER_INFO "#!AMR-WB\n" | |
#define INPUT_SIZE 640 | |
#define OUTPUT_SIZE 1024 | |
unsigned char InputBuf[INPUT_SIZE]; | |
unsigned char OutputBuf[OUTPUT_SIZE]; | |
void usage (void) { | |
printf ("AMR_WB Encoder HELP Displays this text\n"); | |
printf ("\n"); | |
printf ("Usage:\n"); | |
printf ("AMRWBEnc [options] Input_file output_file \n"); | |
printf ("\n"); | |
printf ("Options +M* +F* +DTX \n"); | |
printf ("Support \n"); | |
printf ("Options +M* for seting compression bitrate mode, default is 23.85kbps\n"); | |
printf (" +M0 = 6.6kbps \n"); | |
printf (" +M1 = 8.85kbps \n"); | |
printf (" +M2 = 12.65kbps \n"); | |
printf (" +M3 = 14.25kbps \n"); | |
printf (" +M4 = 15.58kbps \n"); | |
printf (" +M5 = 18.25kbps \n"); | |
printf (" +M6 = 19.85kbps \n"); | |
printf (" +M7 = 23.05kbps \n"); | |
printf (" +M8 = 23.85kbps \n"); | |
printf ("\n"); | |
printf ("Options +F* for setting output frame Type, default is RFC3267 \n"); | |
printf ("+F0 for AMR_WB Defualt bit extern short data frame type \n"); | |
printf ("+F1 for AMR_WB_ITU bit extern short data frame type \n"); | |
printf ("+F2 for RFC3267\n "); | |
printf ("\n"); | |
printf ("Options +DTX enable DTX mode, default is disable.\n"); | |
printf ("File names, input raw PCM data, and output is AMR_WB bit-stream file.\n"); | |
printf ("\n"); | |
} | |
int GetNextBuf(FILE* inFile,unsigned char* dst,int size) | |
{ | |
int size2 = (int)fread(dst, sizeof(signed char), size,inFile); | |
return size2; | |
} | |
typedef int (VO_API * VOGETAUDIOENCAPI) (VO_AUDIO_CODECAPI * pEncHandle); | |
int encode( | |
int mode, | |
short allow_dtx, | |
VOAMRWBFRAMETYPE frameType, | |
const char* srcfile, | |
const char* dstfile | |
) | |
{ | |
int ret = 0; | |
int returnCode; | |
FILE *fsrc = NULL; | |
FILE *fdst = NULL; | |
int framenum = 0; | |
int eofFile = 0; | |
int size1 = 0; | |
int Relens; | |
VO_AUDIO_CODECAPI AudioAPI; | |
VO_MEM_OPERATOR moper; | |
VO_CODEC_INIT_USERDATA useData; | |
VO_HANDLE hCodec; | |
VO_CODECBUFFER inData; | |
VO_CODECBUFFER outData; | |
VO_AUDIO_OUTPUTINFO outFormat; | |
unsigned char *inBuf = InputBuf; | |
unsigned char *outBuf = OutputBuf; | |
#ifdef LINUX | |
void *handle = NULL; | |
void *pfunc; | |
VOGETAUDIOENCAPI pGetAPI; | |
#endif | |
clock_t start, finish; | |
double duration = 0.0; | |
if ((fsrc = fopen (srcfile, "rb")) == NULL) | |
{ | |
ret = -1; | |
goto safe_exit; | |
} | |
if ((fdst = fopen (dstfile, "wb")) == NULL) | |
{ | |
ret = -1; | |
goto safe_exit; | |
} | |
moper.Alloc = cmnMemAlloc; | |
moper.Copy = cmnMemCopy; | |
moper.Free = cmnMemFree; | |
moper.Set = cmnMemSet; | |
moper.Check = cmnMemCheck; | |
useData.memflag = VO_IMF_USERMEMOPERATOR; | |
useData.memData = (VO_PTR)(&moper); | |
#ifdef LINUX | |
handle = dlopen("/data/local/tmp/voAMRWBEnc.so", RTLD_NOW); | |
if(handle == 0) | |
{ | |
printf("open dll error......"); | |
return -1; | |
} | |
pfunc = dlsym(handle, "voGetAMRWBEncAPI"); | |
if(pfunc == 0) | |
{ | |
printf("open function error......"); | |
return -1; | |
} | |
pGetAPI = (VOGETAUDIOENCAPI)pfunc; | |
returnCode = pGetAPI(&AudioAPI); | |
if(returnCode) | |
{ | |
printf("get APIs error......"); | |
return -1; | |
} | |
#else | |
ret = voGetAMRWBEncAPI(&AudioAPI); | |
if(ret) | |
{ | |
ret = -1; | |
printf("get APIs error......"); | |
goto safe_exit; | |
} | |
#endif | |
//####################################### Init Encoding Section ######################################### | |
ret = AudioAPI.Init(&hCodec, VO_AUDIO_CodingAMRWB, &useData); | |
if(ret) | |
{ | |
ret = -1; | |
printf("APIs init error......"); | |
goto safe_exit; | |
} | |
Relens = GetNextBuf(fsrc,InputBuf,INPUT_SIZE); | |
if(Relens!=INPUT_SIZE && !feof(fsrc)) | |
{ | |
ret = -1; //Invalid magic number | |
printf("get next buffer error......"); | |
goto safe_exit; | |
} | |
//###################################### set encode Mode ################################################## | |
ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_FRAMETYPE, &frameType); | |
ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_MODE, &mode); | |
ret = AudioAPI.SetParam(hCodec, VO_PID_AMRWB_DTX, &allow_dtx); | |
if(frameType == VOAMRWB_RFC3267) | |
{ | |
/* write RFC3267 Header info to indicate single channel AMR file storage format */ | |
size1 = (int)strlen(VOAMRWB_RFC3267_HEADER_INFO); | |
memcpy(outBuf, VOAMRWB_RFC3267_HEADER_INFO, size1); | |
outBuf += size1; | |
} | |
//####################################### Encoding Section ######################################### | |
printf(" \n ---------------- Running -------------------------\n "); | |
do{ | |
inData.Buffer = (unsigned char *)inBuf; | |
inData.Length = Relens; | |
outData.Buffer = outBuf; | |
start = clock(); | |
/* decode one amr block */ | |
returnCode = AudioAPI.SetInputData(hCodec,&inData); | |
do { | |
returnCode = AudioAPI.GetOutputData(hCodec,&outData, &outFormat); | |
if(returnCode == 0) | |
{ | |
framenum++; | |
printf(" Frames processed: %hd\r", framenum); | |
if(framenum == 1) | |
{ | |
fwrite(OutputBuf, 1, outData.Length + size1, fdst); | |
fflush(fdst); | |
} | |
else | |
{ | |
fwrite(outData.Buffer, 1, outData.Length, fdst); | |
fflush(fdst); | |
} | |
} | |
else if(returnCode == VO_ERR_LICENSE_ERROR) | |
{ | |
printf("Encoder time reach upper limit......"); | |
goto safe_exit; | |
} | |
} while(returnCode != VO_ERR_INPUT_BUFFER_SMALL); | |
finish = clock(); | |
duration += finish - start; | |
if (!eofFile) { | |
Relens = GetNextBuf(fsrc, InputBuf, INPUT_SIZE); | |
inBuf = InputBuf; | |
if (feof(fsrc) && Relens == 0) | |
eofFile = 1; | |
} | |
} while (!eofFile && returnCode); | |
//####################################### End Encoding Section ######################################### | |
safe_exit: | |
returnCode = AudioAPI.Uninit(hCodec); | |
printf( "\n%2.5f seconds\n", (double)duration/CLOCKS_PER_SEC); | |
if (fsrc) | |
fclose(fsrc); | |
if (fdst) | |
fclose(fdst); | |
#ifdef LINUX | |
dlclose(handle); | |
#endif | |
return ret; | |
} | |
int main(int argc, char **argv) // for gcc compiler; | |
{ | |
int mode, r; | |
int arg, filename=0; | |
char *inFileName = NULL; | |
char *outFileName = NULL; | |
short allow_dtx; | |
VOAMRWBFRAMETYPE frameType; | |
printf("\n"); | |
printf("************************Adaptive Multi-Rate Wide Band Encoder (AMR-WB)*******************************\n"); | |
printf("***********************************DEFINITIONS:*******************************************************\n"); | |
printf("AMR-WB encoder scheme is based on the principle of Algebraic Code Excited Linear Prediction algorithm\n"); | |
printf("The AMR-WB encoder compression MONO liner PCM speech input data at 16kHz sampling rate\n"); | |
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"); | |
printf("The encoder supports output format AMRWB ITU, AMRWB RFC3267.\n"); | |
printf("\n"); | |
/*Encoder Default setting */ | |
mode = VOAMRWB_MD2385; | |
allow_dtx = 0; | |
frameType = VOAMRWB_RFC3267; | |
if(argc < 3){ | |
usage(); | |
return 0; | |
}else{ | |
for (arg = 1; arg < argc; arg++) { | |
if (argv [arg] [0] == '+') { | |
if(argv[arg][1] == 'M') | |
{ | |
switch(argv[arg][2]) | |
{ | |
case '0': mode = VOAMRWB_MD66; | |
break; | |
case '1': mode = VOAMRWB_MD885; | |
break; | |
case '2': mode = VOAMRWB_MD1265; | |
break; | |
case '3': mode = VOAMRWB_MD1425; | |
break; | |
case '4': mode = VOAMRWB_MD1585; | |
break; | |
case '5': mode = VOAMRWB_MD1825; | |
break; | |
case '6': mode = VOAMRWB_MD1985; | |
break; | |
case '7': mode = VOAMRWB_MD2305; | |
break; | |
case '8': mode = VOAMRWB_MD2385; | |
break; | |
default: | |
usage(); | |
printf ("Invalid parameter '%s'.\n", argv [arg]); | |
break; | |
} | |
}else if(argv[arg][1] == 'F') | |
{ | |
switch(argv[arg][2]) | |
{ | |
case '0': frameType = VOAMRWB_DEFAULT; | |
break; | |
case '1': frameType = VOAMRWB_ITU; | |
break; | |
case '2': frameType = VOAMRWB_RFC3267 ; | |
break; | |
default: | |
usage(); | |
printf ("Invalid parameter '%s'.\n", argv [arg]); | |
break; | |
} | |
}else if(strcmp (argv[arg], "+DTX") == 0) | |
{ | |
allow_dtx = 1; | |
} | |
} else { | |
switch (filename) { | |
case 0: | |
inFileName = argv[arg]; | |
break; | |
case 1: | |
outFileName = argv[arg]; | |
break; | |
default: | |
usage (); | |
fprintf (stderr, "Invalid parameter '%s'.\n", argv [arg]); | |
return 0; | |
} | |
filename++; | |
} | |
} | |
} | |
r = encode(mode, allow_dtx, frameType, inFileName, outFileName); | |
if(r) | |
{ | |
fprintf(stderr, "error: %d\n", r); | |
} | |
return r; | |
} | |