blob: 7b5d1b1493b4cee5e15e49f8e76c53befb59f905 [file] [log] [blame]
Benny Prijonobc797312006-03-24 20:44:27 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
Benny Prijono32177c02008-06-20 22:44:47 +00004 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijonobc797312006-03-24 20:44:27 +00005 *
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 */
Benny Prijono1ec70b32006-06-20 15:39:07 +000020
21/**
22 * \page page_pjmedia_samples_resampleplay_c Samples: Using Resample Port
23 *
24 * This example demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to
25 * change the sampling rate of the media streams.
26 *
27 * This file is pjsip-apps/src/samples/resampleplay.c
28 *
29 * \includelineno resampleplay.c
30 */
31
Benny Prijonobc797312006-03-24 20:44:27 +000032#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/* For logging purpose. */
42#define THIS_FILE "resampleplay.c"
43
44
45static const char *desc =
46" FILE \n"
47" \n"
48" resampleplay.c \n"
49" \n"
50" PURPOSE \n"
51" \n"
52" Demonstrate how use resample port to play a WAV file to sound \n"
53" device using different sampling rate. \n"
54" \n"
55" USAGE \n"
56" \n"
57" resampleplay [options] FILE.WAV \n"
58" \n"
59" where options: \n"
60SND_USAGE
61" \n"
62" The WAV file could have mono or stereo channels with arbitrary \n"
63" sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM. \n";
64
65
66int main(int argc, char *argv[])
67{
68 pj_caching_pool cp;
69 pjmedia_endpt *med_endpt;
70 pj_pool_t *pool;
71 pjmedia_port *file_port;
72 pjmedia_port *resample_port;
73 pjmedia_snd_port *snd_port;
74 char tmp[10];
75 pj_status_t status;
76
77 int dev_id = -1;
78 int sampling_rate = CLOCK_RATE;
79 int channel_count = NCHANNELS;
80 int samples_per_frame = NSAMPLES;
81 int bits_per_sample = NBITS;
82 //int ptime;
83 //int down_samples;
84
85 /* Must init PJLIB first: */
86 status = pj_init();
87 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
88
89
90 /* Get options */
91 if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &sampling_rate,
92 &channel_count, &samples_per_frame, &bits_per_sample))
93 {
94 puts("");
95 puts(desc);
96 return 1;
97 }
98
99 if (!argv[pj_optind]) {
100 puts("Error: no file is specified");
101 puts(desc);
102 return 1;
103 }
104
105 /* Must create a pool factory before we can allocate any memory. */
106 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
107
108 /*
109 * Initialize media endpoint.
110 * This will implicitly initialize PJMEDIA too.
111 */
112 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
113 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
114
115 /* Create memory pool for our file player */
116 pool = pj_pool_create( &cp.factory, /* pool factory */
117 "app", /* pool name. */
118 4000, /* init size */
119 4000, /* increment size */
120 NULL /* callback on error */
121 );
122
123 /* Create the file port. */
Benny Prijono15953012006-04-27 22:37:08 +0000124 status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
Benny Prijono6fd4b8f2006-06-22 18:51:50 +0000125 0, &file_port);
Benny Prijonobc797312006-03-24 20:44:27 +0000126 if (status != PJ_SUCCESS) {
127 app_perror(THIS_FILE, "Unable to open file", status);
128 return 1;
129 }
130
131 /* File must have same number of channels. */
132 if (file_port->info.channel_count != (unsigned)channel_count) {
133 PJ_LOG(3,(THIS_FILE, "Error: file has different number of channels. "
134 "Perhaps you'd need -c option?"));
135 pjmedia_port_destroy(file_port);
136 return 1;
137 }
138
139 /* Calculate number of samples per frame to be taken from file port */
140 //ptime = samples_per_frame * 1000 / sampling_rate;
141
142 /* Create the resample port. */
Benny Prijono37235af2006-06-18 02:02:36 +0000143 status = pjmedia_resample_port_create( pool, file_port,
144 sampling_rate, 0,
Benny Prijonobc797312006-03-24 20:44:27 +0000145 &resample_port);
146 if (status != PJ_SUCCESS) {
147 app_perror(THIS_FILE, "Unable to create resample port", status);
148 return 1;
149 }
150
Benny Prijonobc797312006-03-24 20:44:27 +0000151 /* Create sound player port. */
152 status = pjmedia_snd_port_create(
153 pool, /* pool */
154 dev_id, /* device */
155 dev_id, /* device */
156 sampling_rate, /* clock rate. */
157 channel_count, /* # of channels. */
158 samples_per_frame, /* samples per frame. */
159 bits_per_sample, /* bits per sample. */
160 0, /* options */
161 &snd_port /* returned port */
162 );
163 if (status != PJ_SUCCESS) {
164 app_perror(THIS_FILE, "Unable to open sound device", status);
165 return 1;
166 }
167
168 /* Connect resample port to sound device */
169 status = pjmedia_snd_port_connect( snd_port, resample_port);
170 if (status != PJ_SUCCESS) {
171 app_perror(THIS_FILE, "Error connecting sound ports", status);
172 return 1;
173 }
174
175
176 /* Dump memory usage */
177 dump_pool_usage(THIS_FILE, &cp);
178
179 /*
180 * File should be playing and looping now, using sound device's thread.
181 */
182
183
184 /* Sleep to allow log messages to flush */
185 pj_thread_sleep(100);
186
187
188 printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
Benny Prijono15953012006-04-27 22:37:08 +0000189 argv[pj_optind], sampling_rate, file_port->info.clock_rate);
Benny Prijonobc797312006-03-24 20:44:27 +0000190 puts("");
191 puts("Press <ENTER> to stop playing and quit");
192
Benny Prijono32d267b2009-01-01 22:08:21 +0000193 if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
194 puts("EOF while reading stdin, will quit now..");
195 }
Benny Prijonobc797312006-03-24 20:44:27 +0000196
197 /* Start deinitialization: */
198
199
200 /* Destroy sound device */
201 status = pjmedia_snd_port_destroy( snd_port );
202 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
203
204
205 /* Destroy resample port.
206 * This will destroy all downstream ports (e.g. the file port)
207 */
208 status = pjmedia_port_destroy( resample_port );
209 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
210
211
212 /* Release application pool */
213 pj_pool_release( pool );
214
215 /* Destroy media endpoint. */
216 pjmedia_endpt_destroy( med_endpt );
217
218 /* Destroy pool factory */
219 pj_caching_pool_destroy( &cp );
220
Benny Prijonoaf1bb1e2006-11-21 12:39:31 +0000221 /* Shutdown PJLIB */
222 pj_shutdown();
223
Benny Prijonobc797312006-03-24 20:44:27 +0000224
225 /* Done. */
226 return 0;
227
228}
229
230
231