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