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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: mix.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_mix_c Samples: Mixing WAV files
23
 
 *
24
 
 * This file is pjsip-apps/src/samples/mix.c
25
 
 *
26
 
 * \includelineno mix.c
27
 
 */
28
 
 
29
 
#include <pjlib.h>
30
 
#include <pjlib-util.h>
31
 
#include <pjmedia.h>
32
 
 
33
 
#define THIS_FILE   "mix.c"
34
 
 
35
 
static const char *desc = 
36
 
 " mix\n"
37
 
 "\n"
38
 
 " PURPOSE:\n"
39
 
 "  Mix input WAV files and save it to output WAV. Input WAV can have\n"
40
 
 "  different clock rate.\n"
41
 
 "\n"
42
 
 "\n"
43
 
 " USAGE:\n"
44
 
 "  mix [options] output.wav input1.wav [input2.wav] ...\n"
45
 
 "\n"
46
 
 " arguments:\n"
47
 
 "    output.wav    Set the output WAV filename.\n"
48
 
 "    input1.wav    Set the input WAV filename.\n"
49
 
 "    input2.wav    Set the input WAV filename.\n"
50
 
 "\n"
51
 
 " options:\n"
52
 
 "    -c N          Set clock rate to N Hz (default 16000)\n"
53
 
 "    -f            Force write (overwrite output without warning\n"
54
 
;
55
 
 
56
 
#define MAX_WAV     16
57
 
#define PTIME       20
58
 
#define APPEND      1000
59
 
 
60
 
struct wav_input
61
 
{
62
 
    const char      *fname;
63
 
    pjmedia_port    *port;
64
 
    unsigned         slot;
65
 
};
66
 
 
67
 
static int err_ret(const char *title, pj_status_t status)
68
 
{
69
 
    char errmsg[PJ_ERR_MSG_SIZE];
70
 
    pj_strerror(status, errmsg, sizeof(errmsg));
71
 
    PJ_LOG(3,(THIS_FILE, "%s error: %s", title, errmsg));
72
 
    return 1;
73
 
}
74
 
 
75
 
static void usage(void)
76
 
{
77
 
    puts(desc);
78
 
}
79
 
 
80
 
int main(int argc, char *argv[])
81
 
{
82
 
    pj_caching_pool cp;
83
 
    pj_pool_t *pool;
84
 
    pjmedia_endpt *med_ept;
85
 
    unsigned clock_rate = 16000;
86
 
    int c, force=0;
87
 
    const char *out_fname;
88
 
    pjmedia_conf *conf;
89
 
    pjmedia_port *wavout;
90
 
    struct wav_input wav_input[MAX_WAV];
91
 
    pj_size_t longest = 0, processed;
92
 
    unsigned i, input_cnt = 0;
93
 
    pj_status_t status;
94
 
 
95
 
#define CHECK(op)   do { \
96
 
                        status = op; \
97
 
                        if (status != PJ_SUCCESS) \
98
 
                            return err_ret(#op, status); \
99
 
                    } while (0)
100
 
 
101
 
 
102
 
    /* Parse arguments */
103
 
    while ((c=pj_getopt(argc, argv, "c:f")) != -1) {
104
 
        switch (c) {
105
 
        case 'c':
106
 
            clock_rate = atoi(pj_optarg);
107
 
            if (clock_rate < 1000) {
108
 
                puts("Error: invalid clock rate");
109
 
                usage();
110
 
                return -1;
111
 
            }
112
 
            break;
113
 
        case 'f':
114
 
            force = 1;
115
 
            break;
116
 
        }
117
 
    }
118
 
 
119
 
    /* Get output WAV name */
120
 
    if (pj_optind == argc) {
121
 
        puts("Error: no WAV output is specified");
122
 
        usage();
123
 
        return 1;
124
 
    }
125
 
 
126
 
    out_fname = argv[pj_optind++];
127
 
    if (force==0 && pj_file_exists(out_fname)) {
128
 
        char in[8];
129
 
 
130
 
        printf("File %s exists, overwrite? [Y/N] ", out_fname);
131
 
        fflush(stdout);
132
 
        if (fgets(in, sizeof(in), stdin) == NULL)
133
 
            return 1;
134
 
        if (pj_tolower(in[0]) != 'y')
135
 
            return 1;
136
 
    }
137
 
 
138
 
    /* Scan input file names */
139
 
    for (input_cnt=0 ; pj_optind<argc && input_cnt<MAX_WAV; 
140
 
         ++pj_optind, ++input_cnt) 
141
 
    {
142
 
        if (!pj_file_exists(argv[pj_optind])) {
143
 
            printf("Error: input file %s doesn't exist\n",
144
 
                   argv[pj_optind]);
145
 
            return 1;
146
 
        }
147
 
        wav_input[input_cnt].fname = argv[pj_optind];
148
 
        wav_input[input_cnt].port = NULL;
149
 
        wav_input[input_cnt].slot = 0;
150
 
    }
151
 
 
152
 
    if (input_cnt == 0) {
153
 
        puts("Error: no input WAV is specified");
154
 
        return 0;
155
 
    }
156
 
 
157
 
    /* Initialialize */
158
 
    CHECK( pj_init() );
159
 
    CHECK( pjlib_util_init() );
160
 
    pj_caching_pool_init(&cp, NULL, 0);
161
 
    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &med_ept) );
162
 
 
163
 
    pool = pj_pool_create(&cp.factory, "mix", 1000, 1000, NULL);
164
 
 
165
 
    /* Create the bridge */
166
 
    CHECK( pjmedia_conf_create(pool, MAX_WAV+4, clock_rate, 1, 
167
 
                               clock_rate * PTIME / 1000, 16, 
168
 
                               PJMEDIA_CONF_NO_DEVICE, &conf) );
169
 
 
170
 
    /* Create the WAV output */
171
 
    CHECK( pjmedia_wav_writer_port_create(pool, out_fname, clock_rate, 1,
172
 
                                          clock_rate * PTIME / 1000,
173
 
                                          16, 0, 0, &wavout) );
174
 
 
175
 
    /* Create and register each WAV input to the bridge */
176
 
    for (i=0; i<input_cnt; ++i) {
177
 
        pj_ssize_t len;
178
 
 
179
 
        CHECK( pjmedia_wav_player_port_create(pool, wav_input[i].fname, 20,
180
 
                                              PJMEDIA_FILE_NO_LOOP, 0, 
181
 
                                              &wav_input[i].port) );
182
 
        len = pjmedia_wav_player_get_len(wav_input[i].port);
183
 
        len = (pj_ssize_t)(len * 1.0 * clock_rate / 
184
 
                           PJMEDIA_PIA_SRATE(&wav_input[i].port->info));
185
 
        if (len > (pj_ssize_t)longest)
186
 
            longest = len;
187
 
 
188
 
        CHECK( pjmedia_conf_add_port(conf, pool, wav_input[i].port,
189
 
                                     NULL, &wav_input[i].slot));
190
 
 
191
 
        CHECK( pjmedia_conf_connect_port(conf, wav_input[i].slot, 0, 0) );
192
 
    }
193
 
 
194
 
    /* Loop reading frame from the bridge and write it to WAV */
195
 
    processed = 0;
196
 
    while (processed < longest + clock_rate * APPEND * 2 / 1000) {
197
 
        pj_int16_t framebuf[PTIME * 48000 / 1000];
198
 
        pjmedia_port *cp = pjmedia_conf_get_master_port(conf);
199
 
        pjmedia_frame frame;
200
 
 
201
 
        frame.buf = framebuf;
202
 
        frame.size = PJMEDIA_PIA_SPF(&cp->info) * 2;
203
 
        pj_assert(frame.size <= sizeof(framebuf));
204
 
        
205
 
        CHECK( pjmedia_port_get_frame(cp, &frame) );
206
 
 
207
 
        if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
208
 
            pj_bzero(frame.buf, frame.size);
209
 
            frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
210
 
        }
211
 
 
212
 
        CHECK( pjmedia_port_put_frame(wavout, &frame));
213
 
 
214
 
        processed += frame.size;
215
 
    }
216
 
 
217
 
    PJ_LOG(3,(THIS_FILE, "Done. Output duration: %d.%03d",
218
 
              (processed >> 2)/clock_rate,
219
 
              ((processed >> 2)*1000/clock_rate) % 1000));
220
 
 
221
 
    /* Shutdown everything */
222
 
    CHECK( pjmedia_port_destroy(wavout) );
223
 
    for (i=0; i<input_cnt; ++i) {
224
 
        CHECK( pjmedia_conf_remove_port(conf, wav_input[i].slot) );
225
 
        CHECK( pjmedia_port_destroy(wav_input[i].port) );
226
 
    }
227
 
 
228
 
    CHECK(pjmedia_conf_destroy(conf));
229
 
    CHECK(pjmedia_endpt_destroy(med_ept));
230
 
 
231
 
    pj_pool_release(pool);
232
 
    pj_caching_pool_destroy(&cp);
233
 
    pj_shutdown();
234
 
 
235
 
    return 0;
236
 
}
237