blob: 5f150682f621380c5814765a1274c794fe87a6de [file] [log] [blame]
Benny Prijono69f73122006-08-04 11:08:00 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21/**
22 * \page page_pjmedia_samples_aectest_c Samples: AEC Test (aectest.c)
23 *
24 * Play a file to speaker, run AEC, and record the microphone input
25 * to see if echo is coming.
26 *
27 * This file is pjsip-apps/src/samples/aectest.c
28 *
29 * \includelineno aectest.c
30 */
31#include <pjmedia.h>
32#include <pjlib-util.h> /* pj_getopt */
33#include <pjlib.h>
34
35/* For logging purpose. */
36#define THIS_FILE "playfile.c"
37#define PTIME 20
38
39static const char *desc =
40" FILE \n"
41" \n"
42" aectest.c \n"
43" \n"
44" PURPOSE \n"
45" \n"
46" Test the AEC effectiveness. \n"
47" \n"
48" USAGE \n"
49" \n"
50" aectest INPUT.WAV OUTPUT.WAV \n"
51" \n"
52" INPUT.WAV is the file to be played to the speaker. \n"
53" OUTPUT.WAV is the output file containing recorded signal from the\n"
54" microphone.";
55
56
57static void app_perror(const char *sender, const char *title, pj_status_t st)
58{
59 char errmsg[PJ_ERR_MSG_SIZE];
60
61 pj_strerror(st, errmsg, sizeof(errmsg));
62 PJ_LOG(3,(sender, "%s: %s", title, errmsg));
63}
64
65
66/*
67 * main()
68 */
69int main(int argc, char *argv[])
70{
71 pj_caching_pool cp;
72 pjmedia_endpt *med_endpt;
73 pj_pool_t *pool;
74 pjmedia_port *play_port;
75 pjmedia_port *rec_port;
76 pjmedia_port *bidir_port;
77 pjmedia_snd_port *snd;
78 char tmp[10];
79 pj_status_t status;
80
81
82 if (argc != 3) {
83 puts("Error: arguments required");
84 puts(desc);
85 return 1;
86 }
87
88
89 /* Must init PJLIB first: */
90 status = pj_init();
91 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
92
93 /* Must create a pool factory before we can allocate any memory. */
94 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
95
96 /*
97 * Initialize media endpoint.
98 * This will implicitly initialize PJMEDIA too.
99 */
100 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
101 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
102
103 /* Create memory pool for our file player */
104 pool = pj_pool_create( &cp.factory, /* pool factory */
105 "wav", /* pool name. */
106 4000, /* init size */
107 4000, /* increment size */
108 NULL /* callback on error */
109 );
110
111 /* Create file media port from the WAV file */
112 status = pjmedia_wav_player_port_create( pool, /* memory pool */
113 argv[1], /* file to play */
114 PTIME, /* ptime. */
115 0, /* flags */
116 0, /* default buffer */
117 &play_port);
118 if (status != PJ_SUCCESS) {
119 app_perror(THIS_FILE, "Unable to open input WAV file", status);
120 return 1;
121 }
122
123 if (play_port->info.channel_count != 1) {
124 puts("Error: input WAV must have 1 channel audio");
125 return 1;
126 }
127 if (play_port->info.bits_per_sample != 16) {
128 puts("Error: input WAV must be encoded as 16bit PCM");
129 return 1;
130 }
131
132#ifdef PJ_DARWINOS
133 /* Need to force clock rate on MacOS */
134 if (play_port->info.clock_rate != 44100) {
135 pjmedia_port *resample_port;
136
137 status = pjmedia_resample_port_create(pool, play_port, 44100, 0,
138 &resample_port);
139 if (status != PJ_SUCCESS) {
140 app_perror(THIS_FILE, "Unable to create resampling port", status);
141 return 1;
142 }
143
144 data.play_port = resample_port;
145 }
146#endif
147
148 /* Create WAV output file port */
149 status = pjmedia_wav_writer_port_create(pool, argv[2],
150 play_port->info.clock_rate,
151 play_port->info.channel_count,
152 play_port->info.samples_per_frame,
153 play_port->info.bits_per_sample,
154 0, 0, &rec_port);
155 if (status != PJ_SUCCESS) {
156 app_perror(THIS_FILE, "Unable to open output file", status);
157 return 1;
158 }
159
160 /* Create bidirectional port from the WAV ports */
161 pjmedia_bidirectional_port_create(pool, play_port, rec_port, &bidir_port);
162
Benny Prijono69f73122006-08-04 11:08:00 +0000163 /* Create sound device. */
164 status = pjmedia_snd_port_create(pool, -1, -1,
165 play_port->info.clock_rate,
166 play_port->info.channel_count,
167 play_port->info.samples_per_frame,
168 play_port->info.bits_per_sample,
169 0, &snd);
170 if (status != PJ_SUCCESS) {
171 app_perror(THIS_FILE, "Unable to open sound device", status);
172 return 1;
173 }
174
175
Benny Prijonof20687a2006-08-04 18:27:19 +0000176 /* Customize AEC */
177 pjmedia_snd_port_set_aec(snd, pool, 800);
178
Benny Prijono69f73122006-08-04 11:08:00 +0000179 /* Connect sound to the port */
180 pjmedia_snd_port_connect(snd, bidir_port);
181
182
183 puts("");
184 printf("Playing %s and recording to %s\n", argv[1], argv[2]);
185 puts("Press <ENTER> to quit");
186
187 fgets(tmp, sizeof(tmp), stdin);
188
189
190 /* Start deinitialization: */
191
192 /* Destroy sound device */
193 status = pjmedia_snd_port_destroy( snd );
194 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
195
196
197 /* Destroy file port(s) */
198 status = pjmedia_port_destroy( play_port );
199 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
200 status = pjmedia_port_destroy( rec_port );
201 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
202
203
204 /* Release application pool */
205 pj_pool_release( pool );
206
207 /* Destroy media endpoint. */
208 pjmedia_endpt_destroy( med_endpt );
209
210 /* Destroy pool factory */
211 pj_caching_pool_destroy( &cp );
212
Benny Prijonoaf1bb1e2006-11-21 12:39:31 +0000213 /* Shutdown PJLIB */
214 pj_shutdown();
Benny Prijono69f73122006-08-04 11:08:00 +0000215
216 /* Done. */
217 return 0;
218}
219