BLOG | DOCUMENTATION | TRAC

Home --> Documentations --> PJMEDIA Reference

Samples: Using Resample Port

This example demonstrates how to use Resample Port to change the sampling rate of the media streams.

This file is pjsip-apps/src/samples/resampleplay.c

1 /* $Id$ */
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 
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 /* For logging purpose. */
42 #define THIS_FILE "resampleplay.c"
43 
44 
45 static 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"
60 SND_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 
66 int 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. */
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. */
124  status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
125  0, &file_port);
126  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 (PJMEDIA_PIA_CCNT(&file_port->info) != (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. */
143  status = pjmedia_resample_port_create( pool, file_port,
144  sampling_rate, 0,
145  &resample_port);
146  if (status != PJ_SUCCESS) {
147  app_perror(THIS_FILE, "Unable to create resample port", status);
148  return 1;
149  }
150 
151  /* 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",
189  argv[pj_optind], sampling_rate,
190  PJMEDIA_PIA_SRATE(&file_port->info));
191  puts("");
192  puts("Press <ENTER> to stop playing and quit");
193 
194  if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
195  puts("EOF while reading stdin, will quit now..");
196  }
197 
198  /* Start deinitialization: */
199 
200 
201  /* Destroy sound device */
202  status = pjmedia_snd_port_destroy( snd_port );
203  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
204 
205 
206  /* Destroy resample port.
207  * This will destroy all downstream ports (e.g. the file port)
208  */
209  status = pjmedia_port_destroy( resample_port );
210  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
211 
212 
213  /* Release application pool */
214  pj_pool_release( pool );
215 
216  /* Destroy media endpoint. */
217  pjmedia_endpt_destroy( med_endpt );
218 
219  /* Destroy pool factory */
221 
222  /* Shutdown PJLIB */
223  pj_shutdown();
224 
225 
226  /* Done. */
227  return 0;
228 
229 }
230 
231 
232 
PJMEDIA main header file.
#define PJ_ASSERT_RETURN(expr, retval)
pjmedia_port_info info
Definition: port.h:379
void pj_pool_release(pj_pool_t *pool)
pj_status_t pjmedia_port_destroy(pjmedia_port *port)
struct pjmedia_endpt pjmedia_endpt
Definition: types.h:187
pj_status_t pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port)
#define PJ_LOG(level, arg)
struct pjmedia_snd_port pjmedia_snd_port
Definition: sound_port.h:146
int pj_status_t
pj_pool_factory_policy pj_pool_factory_default_policy
pj_status_t pjmedia_resample_port_create(pj_pool_t *pool, pjmedia_port *dn_port, unsigned clock_rate, unsigned options, pjmedia_port **p_port)
Definition: port.h:377
pj_pool_factory factory
pj_status_t pjmedia_snd_port_create(pj_pool_t *pool, int rec_id, int play_id, unsigned clock_rate, unsigned channel_count, unsigned samples_per_frame, unsigned bits_per_sample, unsigned options, pjmedia_snd_port **p_port)
unsigned PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)
Definition: port.h:270
pj_status_t pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt)
Definition: endpoint.h:128
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
pj_status_t pjmedia_wav_player_port_create(pj_pool_t *pool, const char *filename, unsigned ptime, unsigned flags, pj_ssize_t buff_size, pjmedia_port **p_port)
pj_status_t pjmedia_snd_port_connect(pjmedia_snd_port *snd_port, pjmedia_port *port)
pj_pool_t * pj_pool_create(pj_pool_factory *factory, const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
unsigned PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)
Definition: port.h:257
void pj_shutdown(void)
pj_status_t pj_thread_sleep(unsigned msec)
PJ_SUCCESS
pj_status_t pj_init(void)
pj_status_t pjmedia_endpt_destroy(pjmedia_endpt *endpt)
Definition: endpoint.h:169
void pj_caching_pool_destroy(pj_caching_pool *ch_pool)

 


PJMEDIA small footprint Open Source media stack
Copyright (C) 2006-2008 Teluu Inc.