Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjsip-apps / src / samples / recfile.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_recfile_c Samples: Capturing Audio to WAV File
23  *
24  * In this example, we capture audio from the sound device and save it to
25  * WAVE file.
26  *
27  * @see page_pjmedia_samples_playfile_c
28  *
29  * This file is pjsip-apps/src/samples/recfile.c
30  *
31  * \includelineno recfile.c
32  */
33
34 #include <pjmedia.h>
35 #include <pjlib.h>
36
37 #include <stdio.h>
38
39 /* For logging purpose. */
40 #define THIS_FILE   "recfile.c"
41
42
43 /* Configs */
44 #define CLOCK_RATE          44100
45 #define NCHANNELS           2
46 #define SAMPLES_PER_FRAME   (NCHANNELS * (CLOCK_RATE * 10 / 1000))
47 #define BITS_PER_SAMPLE     16
48
49
50 static const char *desc = 
51  " FILE                                     \n"
52  "  recfile.c                               \n"
53  "                                          \n"
54  " PURPOSE:                                 \n"
55  "  Record microphone to WAVE file.         \n"
56  "                                          \n"
57  " USAGE:                                   \n"
58  "  recfile FILE.WAV                        \n"
59  "";
60
61
62 /* Util to display the error message for the specified error code  */
63 static int app_perror( const char *sender, const char *title, 
64                        pj_status_t status)
65 {
66     char errmsg[PJ_ERR_MSG_SIZE];
67
68     PJ_UNUSED_ARG(sender);
69
70     pj_strerror(status, errmsg, sizeof(errmsg));
71
72     printf("%s: %s [code=%d]\n", title, errmsg, status);
73     return 1;
74 }
75
76
77 /*
78  * main()
79  */
80 int main(int argc, char *argv[])
81 {
82     pj_caching_pool cp;
83     pjmedia_endpt *med_endpt;
84     pj_pool_t *pool;
85     pjmedia_port *file_port;
86     pjmedia_snd_port *snd_port;
87     char tmp[10];
88     pj_status_t status;
89
90
91     /* Verify cmd line arguments. */
92     if (argc != 2) {
93         puts("");
94         puts(desc);
95         return 0;
96     }
97
98     /* Must init PJLIB first: */
99     status = pj_init();
100     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
101
102     /* Must create a pool factory before we can allocate any memory. */
103     pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
104
105     /* 
106      * Initialize media endpoint.
107      * This will implicitly initialize PJMEDIA too.
108      */
109     status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
110     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
111
112     /* Create memory pool for our file player */
113     pool = pj_pool_create( &cp.factory,     /* pool factory         */
114                            "app",           /* pool name.           */
115                            4000,            /* init size            */
116                            4000,            /* increment size       */
117                            NULL             /* callback on error    */
118                            );
119
120     /* Create WAVE file writer port. */
121     status = pjmedia_wav_writer_port_create(  pool, argv[1],
122                                               CLOCK_RATE,
123                                               NCHANNELS,
124                                               SAMPLES_PER_FRAME,
125                                               BITS_PER_SAMPLE,
126                                               0, 0, 
127                                               &file_port);
128     if (status != PJ_SUCCESS) {
129         app_perror(THIS_FILE, "Unable to open WAV file for writing", status);
130         return 1;
131     }
132
133     /* Create sound player port. */
134     status = pjmedia_snd_port_create_rec( 
135                  pool,                              /* pool                 */
136                  -1,                                /* use default dev.     */
137                  PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.         */
138                  PJMEDIA_PIA_CCNT(&file_port->info),/* # of channels.       */
139                  PJMEDIA_PIA_SPF(&file_port->info), /* samples per frame.   */
140                  PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.     */
141                  0,                                 /* options              */
142                  &snd_port                          /* returned port        */
143                  );
144     if (status != PJ_SUCCESS) {
145         app_perror(THIS_FILE, "Unable to open sound device", status);
146         return 1;
147     }
148
149     /* Connect file port to the sound player.
150      * Stream playing will commence immediately.
151      */
152     status = pjmedia_snd_port_connect( snd_port, file_port);
153     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
154
155
156
157     /* 
158      * Recording should be started now. 
159      */
160
161
162     /* Sleep to allow log messages to flush */
163     pj_thread_sleep(10);
164
165
166     printf("Recodring %s..\n", argv[1]);
167     puts("");
168     puts("Press <ENTER> to stop recording and quit");
169
170     if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
171         puts("EOF while reading stdin, will quit now..");
172     }
173
174     
175     /* Start deinitialization: */
176
177     /* Destroy sound device */
178     status = pjmedia_snd_port_destroy( snd_port );
179     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
180
181
182     /* Destroy file port */
183     status = pjmedia_port_destroy( file_port );
184     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
185
186
187     /* Release application pool */
188     pj_pool_release( pool );
189
190     /* Destroy media endpoint. */
191     pjmedia_endpt_destroy( med_endpt );
192
193     /* Destroy pool factory */
194     pj_caching_pool_destroy( &cp );
195
196     /* Shutdown PJLIB */
197     pj_shutdown();
198
199
200     /* Done. */
201     return 0;
202 }