~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip-apps/src/samples/stereotest.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: stereotest.c 3664 2011-07-19 03:42:28Z nanang $ */
 
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_stereo_c Samples: Using Stereo Port
 
23
 *
 
24
 * This example demonstrates how to use @ref PJMEDIA_STEREO_PORT to
 
25
 * change the channel count of the media streams.
 
26
 *
 
27
 * This file is pjsip-apps/src/samples/stereotest.c
 
28
 *
 
29
 * \includelineno stereotest.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
#define REC_CLOCK_RATE      16000
 
42
#define PTIME               20
 
43
 
 
44
#define MODE_PLAY           1
 
45
#define MODE_RECORD         2
 
46
 
 
47
 
 
48
/* For logging purpose. */
 
49
#define THIS_FILE   "stereotest.c"
 
50
 
 
51
 
 
52
static const char *desc = 
 
53
" FILE                                                              \n"
 
54
"                                                                   \n"
 
55
"  stereotest.c                                                     \n"
 
56
"                                                                   \n"
 
57
" PURPOSE                                                           \n"
 
58
"                                                                   \n"
 
59
"  Demonstrate how use stereo port to play a WAV file to sound      \n"
 
60
"  device or record to a WAV file from sound device with different  \n"
 
61
"  channel count.                                                   \n"
 
62
"                                                                   \n"
 
63
" USAGE                                                             \n"
 
64
"                                                                   \n"
 
65
"  stereotest [options] WAV                                         \n"
 
66
"                                                                   \n"
 
67
"  Options:                                                         \n"
 
68
"  -m, --mode=N          Operation mode: 1 = playing, 2 = recording.\n"
 
69
"  -C, --rec-ch-cnt=N    Number of channel for recording file.      \n"
 
70
"  -c, --snd-ch-cnt=N    Number of channel for opening sound device.\n"
 
71
"                                                                   \n";
 
72
 
 
73
int main(int argc, char *argv[])
 
74
{
 
75
    pj_caching_pool cp;
 
76
    pjmedia_endpt *med_endpt;
 
77
    pj_pool_t *pool;
 
78
 
 
79
    pjmedia_port *file_port = NULL;
 
80
    pjmedia_port *stereo_port = NULL;
 
81
    pjmedia_snd_port *snd_port = NULL;
 
82
 
 
83
    int dev_id = -1;
 
84
    char tmp[10];
 
85
    pj_status_t status;
 
86
 
 
87
    char *wav_file = NULL;
 
88
    unsigned mode = 0;
 
89
    unsigned rec_ch_cnt = 1;
 
90
    unsigned snd_ch_cnt = 2;
 
91
 
 
92
    enum {
 
93
        OPT_MODE        = 'm',
 
94
        OPT_REC_CHANNEL = 'C',
 
95
        OPT_SND_CHANNEL = 'c',
 
96
    };
 
97
 
 
98
    struct pj_getopt_option long_options[] = {
 
99
        { "mode",           1, 0, OPT_MODE },
 
100
        { "rec-ch-cnt",     1, 0, OPT_REC_CHANNEL },
 
101
        { "snd-ch-cnt",     1, 0, OPT_SND_CHANNEL },
 
102
        { NULL, 0, 0, 0 },
 
103
    };
 
104
 
 
105
    int c;
 
106
    int option_index;
 
107
 
 
108
    /* Must init PJLIB first: */
 
109
    status = pj_init();
 
110
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
 
111
 
 
112
    /* Parse arguments */
 
113
    pj_optind = 0;
 
114
    while((c=pj_getopt_long(argc,argv, "m:C:c:", long_options, &option_index))!=-1) {
 
115
 
 
116
        switch (c) {
 
117
        case OPT_MODE:
 
118
            if (mode) {
 
119
                app_perror(THIS_FILE, "Cannot record and play at once!", 
 
120
                           PJ_EINVAL);
 
121
                return 1;
 
122
            }
 
123
            mode = atoi(pj_optarg);
 
124
            break;
 
125
 
 
126
        case OPT_REC_CHANNEL:
 
127
            rec_ch_cnt = atoi(pj_optarg);
 
128
            break;
 
129
 
 
130
        case OPT_SND_CHANNEL:
 
131
            snd_ch_cnt = atoi(pj_optarg);
 
132
            break;
 
133
 
 
134
        default:
 
135
            printf("Invalid options %s\n", argv[pj_optind]);
 
136
            puts(desc);
 
137
            return 1;
 
138
        }
 
139
 
 
140
    }
 
141
 
 
142
    wav_file = argv[pj_optind];
 
143
 
 
144
    /* Verify arguments. */
 
145
    if (!wav_file) {
 
146
        app_perror(THIS_FILE, "WAV file not specified!", PJ_EINVAL);
 
147
        puts(desc);
 
148
        return 1;
 
149
    }
 
150
    if (!snd_ch_cnt || !rec_ch_cnt || rec_ch_cnt > 6) {
 
151
        app_perror(THIS_FILE, "Invalid or too many channel count!", PJ_EINVAL);
 
152
        puts(desc);
 
153
        return 1;
 
154
    }
 
155
    if (mode != MODE_RECORD && mode != MODE_PLAY) {
 
156
        app_perror(THIS_FILE, "Invalid operation mode!", PJ_EINVAL);
 
157
        puts(desc);
 
158
        return 1;
 
159
    }
 
160
 
 
161
    /* Must create a pool factory before we can allocate any memory. */
 
162
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
 
163
 
 
164
    /* 
 
165
     * Initialize media endpoint.
 
166
     * This will implicitly initialize PJMEDIA too.
 
167
     */
 
168
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
 
169
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
 
170
 
 
171
    /* Create memory pool for our file player */
 
172
    pool = pj_pool_create( &cp.factory,     /* pool factory         */
 
173
                           "app",           /* pool name.           */
 
174
                           4000,            /* init size            */
 
175
                           4000,            /* increment size       */
 
176
                           NULL             /* callback on error    */
 
177
                           );
 
178
 
 
179
    if (mode == MODE_PLAY) {
 
180
        /* Create WAVE file player port. */
 
181
        status = pjmedia_wav_player_port_create( pool, wav_file, PTIME, 0,
 
182
                                                 0, &file_port);
 
183
        if (status != PJ_SUCCESS) {
 
184
            app_perror(THIS_FILE, "Unable to open file", status);
 
185
            return 1;
 
186
        }
 
187
 
 
188
        /* Create sound player port. */
 
189
        status = pjmedia_snd_port_create_player( 
 
190
                     pool,                              /* pool               */
 
191
                     dev_id,                            /* device id.         */
 
192
                     PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.       */
 
193
                     snd_ch_cnt,                        /* # of channels.     */
 
194
                     snd_ch_cnt * PTIME *               /* samples per frame. */
 
195
                     PJMEDIA_PIA_SRATE(&file_port->info) / 1000,
 
196
                     PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.   */
 
197
                     0,                                 /* options            */
 
198
                     &snd_port                          /* returned port      */
 
199
                     );
 
200
        if (status != PJ_SUCCESS) {
 
201
            app_perror(THIS_FILE, "Unable to open sound device", status);
 
202
            return 1;
 
203
        }
 
204
 
 
205
        if (snd_ch_cnt != PJMEDIA_PIA_CCNT(&file_port->info)) {
 
206
            status = pjmedia_stereo_port_create( pool,
 
207
                                                 file_port,
 
208
                                                 snd_ch_cnt,
 
209
                                                 0,
 
210
                                                 &stereo_port);
 
211
            if (status != PJ_SUCCESS) {
 
212
                app_perror(THIS_FILE, "Unable to create stereo port", status);
 
213
                return 1;
 
214
            }
 
215
 
 
216
            status = pjmedia_snd_port_connect(snd_port, stereo_port);
 
217
        } else {
 
218
            status = pjmedia_snd_port_connect(snd_port, file_port);
 
219
        }
 
220
 
 
221
        if (status != PJ_SUCCESS) {
 
222
            app_perror(THIS_FILE, "Unable to connect sound port", status);
 
223
            return 1;
 
224
        }
 
225
 
 
226
    } else {
 
227
        /* Create WAVE file writer port. */
 
228
        status = pjmedia_wav_writer_port_create(pool, wav_file,
 
229
                                                REC_CLOCK_RATE,
 
230
                                                rec_ch_cnt,
 
231
                                                rec_ch_cnt * PTIME * 
 
232
                                                REC_CLOCK_RATE / 1000,
 
233
                                                NBITS,
 
234
                                                0, 0, 
 
235
                                                &file_port);
 
236
        if (status != PJ_SUCCESS) {
 
237
            app_perror(THIS_FILE, "Unable to open file", status);
 
238
            return 1;
 
239
        }
 
240
 
 
241
        /* Create sound player port. */
 
242
        status = pjmedia_snd_port_create_rec( 
 
243
                         pool,                      /* pool                 */
 
244
                         dev_id,                    /* device id.           */
 
245
                         REC_CLOCK_RATE,            /* clock rate.          */
 
246
                         snd_ch_cnt,                /* # of channels.       */
 
247
                         snd_ch_cnt * PTIME * 
 
248
                         REC_CLOCK_RATE / 1000,     /* samples per frame.   */
 
249
                         NBITS,                     /* bits per sample.     */
 
250
                         0,                         /* options              */
 
251
                         &snd_port                  /* returned port        */
 
252
                     );
 
253
        if (status != PJ_SUCCESS) {
 
254
            app_perror(THIS_FILE, "Unable to open sound device", status);
 
255
            return 1;
 
256
        }
 
257
 
 
258
        if (rec_ch_cnt != snd_ch_cnt) {
 
259
            status = pjmedia_stereo_port_create( pool,
 
260
                                                 file_port,
 
261
                                                 snd_ch_cnt,
 
262
                                                 0,
 
263
                                                 &stereo_port);
 
264
            if (status != PJ_SUCCESS) {
 
265
                app_perror(THIS_FILE, "Unable to create stereo port", status);
 
266
                return 1;
 
267
            }
 
268
 
 
269
            status = pjmedia_snd_port_connect(snd_port, stereo_port);
 
270
        } else {
 
271
            status = pjmedia_snd_port_connect(snd_port, file_port);
 
272
        }
 
273
 
 
274
        if (status != PJ_SUCCESS) {
 
275
            app_perror(THIS_FILE, "Unable to connect sound port", status);
 
276
            return 1;
 
277
        }
 
278
    }
 
279
 
 
280
    /* Dump memory usage */
 
281
    dump_pool_usage(THIS_FILE, &cp);
 
282
 
 
283
    /* 
 
284
     * File should be playing and looping now, using sound device's thread. 
 
285
     */
 
286
 
 
287
 
 
288
    /* Sleep to allow log messages to flush */
 
289
    pj_thread_sleep(100);
 
290
 
 
291
    printf("Mode = %s\n", (mode == MODE_PLAY? "playing" : "recording") );
 
292
    printf("File  port channel count = %d\n", PJMEDIA_PIA_CCNT(&file_port->info));
 
293
    printf("Sound port channel count = %d\n", 
 
294
            PJMEDIA_PIA_CCNT(&pjmedia_snd_port_get_port(snd_port)->info));
 
295
    puts("");
 
296
    puts("Press <ENTER> to stop and quit");
 
297
 
 
298
    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
 
299
        puts("EOF while reading stdin, will quit now..");
 
300
    }
 
301
    
 
302
    /* Start deinitialization: */
 
303
 
 
304
 
 
305
    /* Destroy sound device */
 
306
    status = pjmedia_snd_port_destroy( snd_port );
 
307
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
 
308
 
 
309
 
 
310
    /* Destroy stereo port and file_port. 
 
311
     * Stereo port will destroy all downstream ports (e.g. the file port)
 
312
     */
 
313
    status = pjmedia_port_destroy( stereo_port? stereo_port : file_port);
 
314
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
 
315
 
 
316
 
 
317
    /* Release application pool */
 
318
    pj_pool_release( pool );
 
319
 
 
320
    /* Destroy media endpoint. */
 
321
    pjmedia_endpt_destroy( med_endpt );
 
322
 
 
323
    /* Destroy pool factory */
 
324
    pj_caching_pool_destroy( &cp );
 
325
 
 
326
    /* Shutdown PJLIB */
 
327
    pj_shutdown();
 
328
 
 
329
 
 
330
    /* Done. */
 
331
    return 0;
 
332
 
 
333
}
 
334
 
 
335
 
 
336