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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjmedia/src/pjmedia-audiodev/null_dev.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: null_dev.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 */
19
 
#include <pjmedia-audiodev/audiodev_imp.h>
20
 
#include <pj/assert.h>
21
 
#include <pj/log.h>
22
 
#include <pj/os.h>
23
 
 
24
 
#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
25
 
 
26
 
#define THIS_FILE               "null_dev.c"
27
 
 
28
 
/* null_audio device info */
29
 
struct null_audio_dev_info
30
 
{
31
 
    pjmedia_aud_dev_info         info;
32
 
    unsigned                     dev_id;
33
 
};
34
 
 
35
 
/* null_audio factory */
36
 
struct null_audio_factory
37
 
{
38
 
    pjmedia_aud_dev_factory      base;
39
 
    pj_pool_t                   *pool;
40
 
    pj_pool_factory             *pf;
41
 
 
42
 
    unsigned                     dev_count;
43
 
    struct null_audio_dev_info  *dev_info;
44
 
};
45
 
 
46
 
/* Sound stream. */
47
 
struct null_audio_stream
48
 
{
49
 
    pjmedia_aud_stream   base;              /**< Base stream           */
50
 
    pjmedia_aud_param    param;             /**< Settings              */
51
 
    pj_pool_t           *pool;              /**< Memory pool.          */
52
 
 
53
 
    pjmedia_aud_rec_cb   rec_cb;            /**< Capture callback.     */
54
 
    pjmedia_aud_play_cb  play_cb;           /**< Playback callback.    */
55
 
    void                *user_data;         /**< Application data.     */
56
 
};
57
 
 
58
 
 
59
 
/* Prototypes */
60
 
static pj_status_t null_factory_init(pjmedia_aud_dev_factory *f);
61
 
static pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f);
62
 
static pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f);
63
 
static unsigned    null_factory_get_dev_count(pjmedia_aud_dev_factory *f);
64
 
static pj_status_t null_factory_get_dev_info(pjmedia_aud_dev_factory *f,
65
 
                                             unsigned index,
66
 
                                             pjmedia_aud_dev_info *info);
67
 
static pj_status_t null_factory_default_param(pjmedia_aud_dev_factory *f,
68
 
                                              unsigned index,
69
 
                                              pjmedia_aud_param *param);
70
 
static pj_status_t null_factory_create_stream(pjmedia_aud_dev_factory *f,
71
 
                                              const pjmedia_aud_param *param,
72
 
                                              pjmedia_aud_rec_cb rec_cb,
73
 
                                              pjmedia_aud_play_cb play_cb,
74
 
                                              void *user_data,
75
 
                                              pjmedia_aud_stream **p_aud_strm);
76
 
 
77
 
static pj_status_t null_stream_get_param(pjmedia_aud_stream *strm,
78
 
                                         pjmedia_aud_param *param);
79
 
static pj_status_t null_stream_get_cap(pjmedia_aud_stream *strm,
80
 
                                       pjmedia_aud_dev_cap cap,
81
 
                                       void *value);
82
 
static pj_status_t null_stream_set_cap(pjmedia_aud_stream *strm,
83
 
                                       pjmedia_aud_dev_cap cap,
84
 
                                       const void *value);
85
 
static pj_status_t null_stream_start(pjmedia_aud_stream *strm);
86
 
static pj_status_t null_stream_stop(pjmedia_aud_stream *strm);
87
 
static pj_status_t null_stream_destroy(pjmedia_aud_stream *strm);
88
 
 
89
 
/* Operations */
90
 
static pjmedia_aud_dev_factory_op factory_op =
91
 
{
92
 
    &null_factory_init,
93
 
    &null_factory_destroy,
94
 
    &null_factory_get_dev_count,
95
 
    &null_factory_get_dev_info,
96
 
    &null_factory_default_param,
97
 
    &null_factory_create_stream,
98
 
    &null_factory_refresh
99
 
};
100
 
 
101
 
static pjmedia_aud_stream_op stream_op =
102
 
{
103
 
    &null_stream_get_param,
104
 
    &null_stream_get_cap,
105
 
    &null_stream_set_cap,
106
 
    &null_stream_start,
107
 
    &null_stream_stop,
108
 
    &null_stream_destroy
109
 
};
110
 
 
111
 
 
112
 
/****************************************************************************
113
 
 * Factory operations
114
 
 */
115
 
/*
116
 
 * Init null_audio audio driver.
117
 
 */
118
 
pjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf)
119
 
{
120
 
    struct null_audio_factory *f;
121
 
    pj_pool_t *pool;
122
 
 
123
 
    pool = pj_pool_create(pf, "null audio", 1000, 1000, NULL);
124
 
    f = PJ_POOL_ZALLOC_T(pool, struct null_audio_factory);
125
 
    f->pf = pf;
126
 
    f->pool = pool;
127
 
    f->base.op = &factory_op;
128
 
 
129
 
    return &f->base;
130
 
}
131
 
 
132
 
 
133
 
/* API: init factory */
134
 
static pj_status_t null_factory_init(pjmedia_aud_dev_factory *f)
135
 
{
136
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
137
 
    struct null_audio_dev_info *ndi;
138
 
 
139
 
    /* Initialize input and output devices here */
140
 
    nf->dev_count = 1;
141
 
    nf->dev_info = (struct null_audio_dev_info*)
142
 
                   pj_pool_calloc(nf->pool, nf->dev_count,
143
 
                                  sizeof(struct null_audio_dev_info));
144
 
    ndi = &nf->dev_info[0];
145
 
    pj_bzero(ndi, sizeof(*ndi));
146
 
    strcpy(ndi->info.name, "null device");
147
 
    strcpy(ndi->info.driver, "null");
148
 
    ndi->info.input_count = 1;
149
 
    ndi->info.output_count = 1;
150
 
    ndi->info.default_samples_per_sec = 16000;
151
 
    /* Set the device capabilities here */
152
 
    ndi->info.caps = 0;
153
 
 
154
 
    PJ_LOG(4, (THIS_FILE, "null audio initialized"));
155
 
 
156
 
    return PJ_SUCCESS;
157
 
}
158
 
 
159
 
/* API: destroy factory */
160
 
static pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f)
161
 
{
162
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
163
 
    pj_pool_t *pool = nf->pool;
164
 
 
165
 
    nf->pool = NULL;
166
 
    pj_pool_release(pool);
167
 
 
168
 
    return PJ_SUCCESS;
169
 
}
170
 
 
171
 
/* API: refresh the list of devices */
172
 
static pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f)
173
 
{
174
 
    PJ_UNUSED_ARG(f);
175
 
    return PJ_SUCCESS;
176
 
}
177
 
 
178
 
/* API: get number of devices */
179
 
static unsigned null_factory_get_dev_count(pjmedia_aud_dev_factory *f)
180
 
{
181
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
182
 
    return nf->dev_count;
183
 
}
184
 
 
185
 
/* API: get device info */
186
 
static pj_status_t null_factory_get_dev_info(pjmedia_aud_dev_factory *f,
187
 
                                             unsigned index,
188
 
                                             pjmedia_aud_dev_info *info)
189
 
{
190
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
191
 
 
192
 
    PJ_ASSERT_RETURN(index < nf->dev_count, PJMEDIA_EAUD_INVDEV);
193
 
 
194
 
    pj_memcpy(info, &nf->dev_info[index].info, sizeof(*info));
195
 
 
196
 
    return PJ_SUCCESS;
197
 
}
198
 
 
199
 
/* API: create default device parameter */
200
 
static pj_status_t null_factory_default_param(pjmedia_aud_dev_factory *f,
201
 
                                              unsigned index,
202
 
                                              pjmedia_aud_param *param)
203
 
{
204
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
205
 
    struct null_audio_dev_info *di = &nf->dev_info[index];
206
 
 
207
 
    PJ_ASSERT_RETURN(index < nf->dev_count, PJMEDIA_EAUD_INVDEV);
208
 
 
209
 
    pj_bzero(param, sizeof(*param));
210
 
    if (di->info.input_count && di->info.output_count) {
211
 
        param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
212
 
        param->rec_id = index;
213
 
        param->play_id = index;
214
 
    } else if (di->info.input_count) {
215
 
        param->dir = PJMEDIA_DIR_CAPTURE;
216
 
        param->rec_id = index;
217
 
        param->play_id = PJMEDIA_AUD_INVALID_DEV;
218
 
    } else if (di->info.output_count) {
219
 
        param->dir = PJMEDIA_DIR_PLAYBACK;
220
 
        param->play_id = index;
221
 
        param->rec_id = PJMEDIA_AUD_INVALID_DEV;
222
 
    } else {
223
 
        return PJMEDIA_EAUD_INVDEV;
224
 
    }
225
 
 
226
 
    /* Set the mandatory settings here */
227
 
    /* The values here are just some examples */
228
 
    param->clock_rate = di->info.default_samples_per_sec;
229
 
    param->channel_count = 1;
230
 
    param->samples_per_frame = di->info.default_samples_per_sec * 20 / 1000;
231
 
    param->bits_per_sample = 16;
232
 
 
233
 
    /* Set the device capabilities here */
234
 
    param->flags = 0;
235
 
 
236
 
    return PJ_SUCCESS;
237
 
}
238
 
 
239
 
/* API: create stream */
240
 
static pj_status_t null_factory_create_stream(pjmedia_aud_dev_factory *f,
241
 
                                              const pjmedia_aud_param *param,
242
 
                                              pjmedia_aud_rec_cb rec_cb,
243
 
                                              pjmedia_aud_play_cb play_cb,
244
 
                                              void *user_data,
245
 
                                              pjmedia_aud_stream **p_aud_strm)
246
 
{
247
 
    struct null_audio_factory *nf = (struct null_audio_factory*)f;
248
 
    pj_pool_t *pool;
249
 
    struct null_audio_stream *strm;
250
 
 
251
 
    /* Create and Initialize stream descriptor */
252
 
    pool = pj_pool_create(nf->pf, "null_audio-dev", 1000, 1000, NULL);
253
 
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
254
 
 
255
 
    strm = PJ_POOL_ZALLOC_T(pool, struct null_audio_stream);
256
 
    pj_memcpy(&strm->param, param, sizeof(*param));
257
 
    strm->pool = pool;
258
 
    strm->rec_cb = rec_cb;
259
 
    strm->play_cb = play_cb;
260
 
    strm->user_data = user_data;
261
 
 
262
 
    /* Create player stream here */
263
 
    if (param->dir & PJMEDIA_DIR_PLAYBACK) {
264
 
    }
265
 
 
266
 
    /* Create capture stream here */
267
 
    if (param->dir & PJMEDIA_DIR_CAPTURE) {
268
 
    }
269
 
 
270
 
    /* Apply the remaining settings */
271
 
    /* Below is an example if you want to set the output volume */
272
 
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {
273
 
        null_stream_set_cap(&strm->base,
274
 
                            PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
275
 
                            &param->output_vol);
276
 
    }
277
 
 
278
 
    /* Done */
279
 
    strm->base.op = &stream_op;
280
 
    *p_aud_strm = &strm->base;
281
 
 
282
 
    return PJ_SUCCESS;
283
 
}
284
 
 
285
 
/* API: Get stream info. */
286
 
static pj_status_t null_stream_get_param(pjmedia_aud_stream *s,
287
 
                                         pjmedia_aud_param *pi)
288
 
{
289
 
    struct null_audio_stream *strm = (struct null_audio_stream*)s;
290
 
 
291
 
    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
292
 
 
293
 
    pj_memcpy(pi, &strm->param, sizeof(*pi));
294
 
 
295
 
    /* Example: Update the volume setting */
296
 
    if (null_stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
297
 
                            &pi->output_vol) == PJ_SUCCESS)
298
 
    {
299
 
        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
300
 
    }
301
 
 
302
 
    return PJ_SUCCESS;
303
 
}
304
 
 
305
 
/* API: get capability */
306
 
static pj_status_t null_stream_get_cap(pjmedia_aud_stream *s,
307
 
                                       pjmedia_aud_dev_cap cap,
308
 
                                       void *pval)
309
 
{
310
 
    struct null_audio_stream *strm = (struct null_audio_stream*)s;
311
 
 
312
 
    PJ_UNUSED_ARG(strm);
313
 
 
314
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
315
 
 
316
 
    /* Example: Get the output's volume setting */
317
 
    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING)
318
 
    {
319
 
        /* Output volume setting */
320
 
        *(unsigned*)pval = 0; // retrieve output device's volume here
321
 
        return PJ_SUCCESS;
322
 
    } else {
323
 
        return PJMEDIA_EAUD_INVCAP;
324
 
    }
325
 
}
326
 
 
327
 
/* API: set capability */
328
 
static pj_status_t null_stream_set_cap(pjmedia_aud_stream *s,
329
 
                                       pjmedia_aud_dev_cap cap,
330
 
                                       const void *pval)
331
 
{
332
 
    struct null_audio_stream *strm = (struct null_audio_stream*)s;
333
 
 
334
 
    PJ_UNUSED_ARG(strm);
335
 
 
336
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
337
 
 
338
 
    /* Example */
339
 
    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING)
340
 
    {
341
 
        /* Output volume setting */
342
 
        // set output's volume level here
343
 
        return PJ_SUCCESS;
344
 
    }
345
 
 
346
 
    return PJMEDIA_EAUD_INVCAP;
347
 
}
348
 
 
349
 
/* API: Start stream. */
350
 
static pj_status_t null_stream_start(pjmedia_aud_stream *strm)
351
 
{
352
 
    struct null_audio_stream *stream = (struct null_audio_stream*)strm;
353
 
 
354
 
    PJ_UNUSED_ARG(stream);
355
 
 
356
 
    PJ_LOG(4, (THIS_FILE, "Starting null audio stream"));
357
 
 
358
 
    return PJ_SUCCESS;
359
 
}
360
 
 
361
 
/* API: Stop stream. */
362
 
static pj_status_t null_stream_stop(pjmedia_aud_stream *strm)
363
 
{
364
 
    struct null_audio_stream *stream = (struct null_audio_stream*)strm;
365
 
 
366
 
    PJ_UNUSED_ARG(stream);
367
 
 
368
 
    PJ_LOG(4, (THIS_FILE, "Stopping null audio stream"));
369
 
 
370
 
    return PJ_SUCCESS;
371
 
}
372
 
 
373
 
 
374
 
/* API: Destroy stream. */
375
 
static pj_status_t null_stream_destroy(pjmedia_aud_stream *strm)
376
 
{
377
 
    struct null_audio_stream *stream = (struct null_audio_stream*)strm;
378
 
 
379
 
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
380
 
 
381
 
    null_stream_stop(strm);
382
 
 
383
 
    pj_pool_release(stream->pool);
384
 
 
385
 
    return PJ_SUCCESS;
386
 
}
387
 
 
388
 
#endif  /* PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO */