Changeset 2198 for pjproject/trunk/pjsip-apps/src/samples/aectest.c
- Timestamp:
- Aug 9, 2008 5:40:22 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/samples/aectest.c
r2039 r2198 33 33 #include <pjlib.h> 34 34 35 /* For logging purpose. */ 36 #define THIS_FILE "playfile.c" 35 #define THIS_FILE "aectest.c" 37 36 #define PTIME 20 38 #define TAIL_LENGTH 80037 #define TAIL_LENGTH 200 39 38 40 39 static const char *desc = … … 49 48 " USAGE \n" 50 49 " \n" 51 " aectest INPUT.WAV OUTPUT.WAV \n" 52 " \n" 53 " INPUT.WAV is the file to be played to the speaker. \n" 54 " OUTPUT.WAV is the output file containing recorded signal from the\n" 55 " microphone."; 56 50 " aectest [options] <PLAY.WAV> <REC.WAV> <OUTPUT.WAV> \n" 51 " \n" 52 " <PLAY.WAV> is the signal played to the speaker. \n" 53 " <REC.WAV> is the signal captured from the microphone. \n" 54 " <OUTPUT.WAV> is the output file to store the test result \n" 55 "\n" 56 " options:\n" 57 " -d The delay between playback and capture in ms. Default is zero.\n" 58 " -l Set the echo tail length in ms. Default is 200 ms \n" 59 " -a Algorithm: 0=default, 1=speex, 3=echo suppress \n"; 60 61 /* 62 * Sample session: 63 * 64 * -d 100 -a 1 ../bin/orig8.wav ../bin/echo8.wav ../bin/result8.wav 65 */ 57 66 58 67 static void app_perror(const char *sender, const char *title, pj_status_t st) … … 73 82 pjmedia_endpt *med_endpt; 74 83 pj_pool_t *pool; 75 pjmedia_port *play_port; 76 pjmedia_port *rec_port; 77 pjmedia_port *bidir_port; 78 pjmedia_snd_port *snd; 79 char tmp[10]; 84 pjmedia_port *wav_play; 85 pjmedia_port *wav_rec; 86 pjmedia_port *wav_out; 80 87 pj_status_t status; 81 82 83 if (argc != 3) { 84 puts("Error: arguments required"); 88 pjmedia_echo_state *ec; 89 pjmedia_frame play_frame, rec_frame; 90 unsigned opt = 0; 91 unsigned latency_ms = 0; 92 unsigned tail_ms = TAIL_LENGTH; 93 pj_timestamp t0, t1; 94 int c; 95 96 pj_optind = 0; 97 while ((c=pj_getopt(argc, argv, "d:l:a:")) !=-1) { 98 switch (c) { 99 case 'd': 100 latency_ms = atoi(pj_optarg); 101 break; 102 case 'l': 103 tail_ms = atoi(pj_optarg); 104 break; 105 case 'a': 106 { 107 int alg = atoi(pj_optarg); 108 switch (alg) { 109 case 0: 110 opt = 0; 111 case 1: 112 opt = PJMEDIA_ECHO_SPEEX; 113 break; 114 case 3: 115 opt = PJMEDIA_ECHO_SIMPLE; 116 break; 117 default: 118 puts("Invalid algorithm"); 119 puts(desc); 120 return 1; 121 } 122 } 123 break; 124 } 125 } 126 127 if (argc - pj_optind != 3) { 128 puts("Error: missing argument(s)"); 85 129 puts(desc); 86 130 return 1; 87 131 } 88 89 132 90 133 /* Must init PJLIB first: */ … … 110 153 ); 111 154 112 /* Create file media port from the WAV file */ 113 status = pjmedia_wav_player_port_create( pool, /* memory pool */ 114 argv[1], /* file to play */ 115 PTIME, /* ptime. */ 116 0, /* flags */ 117 0, /* default buffer */ 118 &play_port); 119 if (status != PJ_SUCCESS) { 120 app_perror(THIS_FILE, "Unable to open input WAV file", status); 121 return 1; 122 } 123 124 if (play_port->info.channel_count != 1) { 125 puts("Error: input WAV must have 1 channel audio"); 126 return 1; 127 } 128 if (play_port->info.bits_per_sample != 16) { 129 puts("Error: input WAV must be encoded as 16bit PCM"); 130 return 1; 131 } 132 133 #ifdef PJ_DARWINOS 134 /* Need to force clock rate on MacOS */ 135 if (play_port->info.clock_rate != 44100) { 136 pjmedia_port *resample_port; 137 138 status = pjmedia_resample_port_create(pool, play_port, 44100, 0, 139 &resample_port); 140 if (status != PJ_SUCCESS) { 141 app_perror(THIS_FILE, "Unable to create resampling port", status); 142 return 1; 143 } 144 145 data.play_port = resample_port; 146 } 147 #endif 148 149 /* Create WAV output file port */ 150 status = pjmedia_wav_writer_port_create(pool, argv[2], 151 play_port->info.clock_rate, 152 play_port->info.channel_count, 153 play_port->info.samples_per_frame, 154 play_port->info.bits_per_sample, 155 0, 0, &rec_port); 156 if (status != PJ_SUCCESS) { 157 app_perror(THIS_FILE, "Unable to open output file", status); 158 return 1; 159 } 160 161 /* Create bidirectional port from the WAV ports */ 162 pjmedia_bidirectional_port_create(pool, play_port, rec_port, &bidir_port); 163 164 /* Create sound device. */ 165 status = pjmedia_snd_port_create(pool, -1, -1, 166 play_port->info.clock_rate, 167 play_port->info.channel_count, 168 play_port->info.samples_per_frame, 169 play_port->info.bits_per_sample, 170 0, &snd); 171 if (status != PJ_SUCCESS) { 172 app_perror(THIS_FILE, "Unable to open sound device", status); 173 return 1; 174 } 175 176 177 /* Customize AEC */ 178 pjmedia_snd_port_set_ec(snd, pool, TAIL_LENGTH, 0); 179 180 /* Connect sound to the port */ 181 pjmedia_snd_port_connect(snd, bidir_port); 182 183 184 puts(""); 185 printf("Playing %s and recording to %s\n", argv[1], argv[2]); 186 puts("Press <ENTER> to quit"); 187 188 fgets(tmp, sizeof(tmp), stdin); 189 155 /* Open wav_play */ 156 status = pjmedia_wav_player_port_create(pool, argv[pj_optind], PTIME, 157 PJMEDIA_FILE_NO_LOOP, 0, 158 &wav_play); 159 if (status != PJ_SUCCESS) { 160 app_perror(THIS_FILE, "Error opening playback WAV file", status); 161 return 1; 162 } 190 163 191 /* Start deinitialization: */ 192 193 /* Destroy sound device */ 194 status = pjmedia_snd_port_destroy( snd ); 195 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 196 164 /* Open recorded wav */ 165 status = pjmedia_wav_player_port_create(pool, argv[pj_optind+1], PTIME, 166 PJMEDIA_FILE_NO_LOOP, 0, 167 &wav_rec); 168 if (status != PJ_SUCCESS) { 169 app_perror(THIS_FILE, "Error opening recorded WAV file", status); 170 return 1; 171 } 172 173 /* play and rec WAVs must have the same clock rate */ 174 if (wav_play->info.clock_rate != wav_rec->info.clock_rate) { 175 puts("Error: clock rate mismatch in the WAV files"); 176 return 1; 177 } 178 179 /* .. and channel count */ 180 if (wav_play->info.channel_count != wav_rec->info.channel_count) { 181 puts("Error: clock rate mismatch in the WAV files"); 182 return 1; 183 } 184 185 /* Create output wav */ 186 status = pjmedia_wav_writer_port_create(pool, argv[pj_optind+2], 187 wav_play->info.clock_rate, 188 wav_play->info.channel_count, 189 wav_play->info.samples_per_frame, 190 wav_play->info.bits_per_sample, 191 0, 0, &wav_out); 192 if (status != PJ_SUCCESS) { 193 app_perror(THIS_FILE, "Error opening output WAV file", status); 194 return 1; 195 } 196 197 /* Create echo canceller */ 198 status = pjmedia_echo_create2(pool, wav_play->info.clock_rate, 199 wav_play->info.channel_count, 200 wav_play->info.samples_per_frame, 201 tail_ms, latency_ms, 202 opt, &ec); 203 if (status != PJ_SUCCESS) { 204 app_perror(THIS_FILE, "Error creating EC", status); 205 return 1; 206 } 207 208 209 /* Processing loop */ 210 play_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1); 211 rec_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1); 212 pj_get_timestamp(&t0); 213 for (;;) { 214 play_frame.size = wav_play->info.samples_per_frame << 1; 215 status = pjmedia_port_get_frame(wav_play, &play_frame); 216 if (status != PJ_SUCCESS) 217 break; 218 219 status = pjmedia_echo_playback(ec, (short*)play_frame.buf); 220 221 rec_frame.size = wav_play->info.samples_per_frame << 1; 222 status = pjmedia_port_get_frame(wav_rec, &rec_frame); 223 if (status != PJ_SUCCESS) 224 break; 225 226 status = pjmedia_echo_capture(ec, (short*)rec_frame.buf, 0); 227 228 //status = pjmedia_echo_cancel(ec, (short*)rec_frame.buf, 229 // (short*)play_frame.buf, 0, NULL); 230 231 pjmedia_port_put_frame(wav_out, &rec_frame); 232 } 233 pj_get_timestamp(&t1); 234 235 PJ_LOG(3,(THIS_FILE, "Completed in %u msec\n", pj_elapsed_msec(&t0, &t1))); 197 236 198 237 /* Destroy file port(s) */ 199 status = pjmedia_port_destroy( play_port ); 200 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 201 status = pjmedia_port_destroy( rec_port ); 202 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 203 238 status = pjmedia_port_destroy( wav_play ); 239 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 240 status = pjmedia_port_destroy( wav_rec ); 241 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 242 status = pjmedia_port_destroy( wav_out ); 243 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); 244 245 /* Destroy ec */ 246 pjmedia_echo_destroy(ec); 204 247 205 248 /* Release application pool */
Note: See TracChangeset
for help on using the changeset viewer.