~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* 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
 
}