Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjsip-apps / src / samples / resampleplay.c
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19  */
20
21 /**
22  * \page page_pjmedia_samples_resampleplay_c Samples: Using Resample Port
23  *
24  * This example demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to
25  * change the sampling rate of the media streams.
26  *
27  * This file is pjsip-apps/src/samples/resampleplay.c
28  *
29  * \includelineno resampleplay.c
30  */
31
32 #include <pjmedia.h>
33 #include <pjlib-util.h>
34 #include <pjlib.h>
35
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include "util.h"
40
41 /* For logging purpose. */
42 #define THIS_FILE   "resampleplay.c"
43
44
45 static const char *desc = 
46 " FILE                                                              \n"
47 "                                                                   \n"
48 "  resampleplay.c                                                   \n"
49 "                                                                   \n"
50 " PURPOSE                                                           \n"
51 "                                                                   \n"
52 "  Demonstrate how use resample port to play a WAV file to sound    \n"
53 "  device using different sampling rate.                            \n"
54 "                                                                   \n"
55 " USAGE                                                             \n"
56 "                                                                   \n"
57 "  resampleplay [options] FILE.WAV                                  \n"
58 "                                                                   \n"
59 " where options:                                                    \n"
60 SND_USAGE
61 "                                                                   \n"
62 "  The WAV file could have mono or stereo channels with arbitrary   \n"
63 "  sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM.   \n";
64
65
66 int main(int argc, char *argv[])
67 {
68     pj_caching_pool cp;
69     pjmedia_endpt *med_endpt;
70     pj_pool_t *pool;
71     pjmedia_port *file_port;
72     pjmedia_port *resample_port;
73     pjmedia_snd_port *snd_port;
74     char tmp[10];
75     pj_status_t status;
76
77     int dev_id = -1;
78     int sampling_rate = CLOCK_RATE;
79     int channel_count = NCHANNELS;
80     int samples_per_frame = NSAMPLES;
81     int bits_per_sample = NBITS;
82     //int ptime;
83     //int down_samples;
84
85     /* Must init PJLIB first: */
86     status = pj_init();
87     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
88
89
90     /* Get options */
91     if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &sampling_rate,
92                         &channel_count, &samples_per_frame, &bits_per_sample))
93     {
94         puts("");
95         puts(desc);
96         return 1;
97     }
98
99     if (!argv[pj_optind]) {
100         puts("Error: no file is specified");
101         puts(desc);
102         return 1;
103     }
104
105     /* Must create a pool factory before we can allocate any memory. */
106     pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
107
108     /* 
109      * Initialize media endpoint.
110      * This will implicitly initialize PJMEDIA too.
111      */
112     status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
113     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
114
115     /* Create memory pool for our file player */
116     pool = pj_pool_create( &cp.factory,     /* pool factory         */
117                            "app",           /* pool name.           */
118                            4000,            /* init size            */
119                            4000,            /* increment size       */
120                            NULL             /* callback on error    */
121                            );
122
123     /* Create the file port. */
124     status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
125                                              0, &file_port);
126     if (status != PJ_SUCCESS) {
127         app_perror(THIS_FILE, "Unable to open file", status);
128         return 1;
129     }
130
131     /* File must have same number of channels. */
132     if (PJMEDIA_PIA_CCNT(&file_port->info) != (unsigned)channel_count) {
133         PJ_LOG(3,(THIS_FILE, "Error: file has different number of channels. "
134                              "Perhaps you'd need -c option?"));
135         pjmedia_port_destroy(file_port);
136         return 1;
137     }
138
139     /* Calculate number of samples per frame to be taken from file port */
140     //ptime = samples_per_frame * 1000 / sampling_rate;
141
142     /* Create the resample port. */
143     status = pjmedia_resample_port_create( pool, file_port,
144                                            sampling_rate, 0,
145                                            &resample_port);
146     if (status != PJ_SUCCESS) {
147         app_perror(THIS_FILE, "Unable to create resample port", status);
148         return 1;
149     }
150
151     /* Create sound player port. */
152     status = pjmedia_snd_port_create( 
153                  pool,                  /* pool                     */
154                  dev_id,                /* device                   */
155                  dev_id,                /* device                   */
156                  sampling_rate,         /* clock rate.              */
157                  channel_count,         /* # of channels.           */
158                  samples_per_frame,     /* samples per frame.       */
159                  bits_per_sample,       /* bits per sample.         */
160                  0,                     /* options                  */
161                  &snd_port              /* returned port            */
162                  );
163     if (status != PJ_SUCCESS) {
164         app_perror(THIS_FILE, "Unable to open sound device", status);
165         return 1;
166     }
167
168     /* Connect resample port to sound device */
169     status = pjmedia_snd_port_connect( snd_port, resample_port);
170     if (status != PJ_SUCCESS) {
171         app_perror(THIS_FILE, "Error connecting sound ports", status);
172         return 1;
173     }
174
175
176     /* Dump memory usage */
177     dump_pool_usage(THIS_FILE, &cp);
178
179     /* 
180      * File should be playing and looping now, using sound device's thread. 
181      */
182
183
184     /* Sleep to allow log messages to flush */
185     pj_thread_sleep(100);
186
187
188     printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
189            argv[pj_optind], sampling_rate,
190            PJMEDIA_PIA_SRATE(&file_port->info));
191     puts("");
192     puts("Press <ENTER> to stop playing and quit");
193
194     if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
195         puts("EOF while reading stdin, will quit now..");
196     }
197     
198     /* Start deinitialization: */
199
200
201     /* Destroy sound device */
202     status = pjmedia_snd_port_destroy( snd_port );
203     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
204
205
206     /* Destroy resample port. 
207      * This will destroy all downstream ports (e.g. the file port)
208      */
209     status = pjmedia_port_destroy( resample_port );
210     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
211
212
213     /* Release application pool */
214     pj_pool_release( pool );
215
216     /* Destroy media endpoint. */
217     pjmedia_endpt_destroy( med_endpt );
218
219     /* Destroy pool factory */
220     pj_caching_pool_destroy( &cp );
221
222     /* Shutdown PJLIB */
223     pj_shutdown();
224
225
226     /* Done. */
227     return 0;
228
229 }
230
231
232