blob: 8c51271f42cd7bc308b4a727409f492c7914403c [file] [log] [blame]
Benny Prijonocbc1c472006-03-19 00:50:23 +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 Prijonocbc1c472006-03-19 00:50:23 +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 */
20
21#include <pjmedia.h>
Benny Prijonobc797312006-03-24 20:44:27 +000022#include <pjlib-util.h>
23#include <pjlib.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27#include "util.h"
28
Benny Prijonocbc1c472006-03-19 00:50:23 +000029
Benny Prijono1ec70b32006-06-20 15:39:07 +000030/**
31 * \page page_pjmedia_samples_playfile_c Samples: Playing WAV File to Sound Device
32 *
33 * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY and
34 * @ref PJMED_SND_PORT. In this example, we open both the file and sound
35 * device, and connect the two of them, and voila! Sound will be playing
36 * the contents of the file.
37 *
38 * @see page_pjmedia_samples_recfile_c
39 *
40 * This file is pjsip-apps/src/samples/playfile.c
41 *
42 * \includelineno playfile.c
43 */
44
45
Benny Prijonocbc1c472006-03-19 00:50:23 +000046/*
47 * playfile.c
48 *
49 * PURPOSE:
50 * Play a WAV file to sound player device.
51 *
52 * USAGE:
53 * playfile FILE.WAV
54 *
55 * The WAV file could have mono or stereo channels with arbitrary
56 * sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM.
57 *
58 */
59
Benny Prijonocbc1c472006-03-19 00:50:23 +000060
61/* For logging purpose. */
62#define THIS_FILE "playfile.c"
63
64
Benny Prijonobc797312006-03-24 20:44:27 +000065static const char *desc =
66" FILE \n"
67" \n"
68" playfile.c \n"
69" \n"
70" PURPOSE \n"
71" \n"
72" Demonstrate how to play a WAV file. \n"
73" \n"
74" USAGE \n"
75" \n"
76" playfile FILE.WAV \n"
77" \n"
78" The WAV file could have mono or stereo channels with arbitrary \n"
79" sampling rate, but MUST contain uncompressed (i.e. 16bit) PCM. \n";
Benny Prijonocbc1c472006-03-19 00:50:23 +000080
81
82/*
83 * main()
84 */
85int main(int argc, char *argv[])
86{
87 pj_caching_pool cp;
88 pjmedia_endpt *med_endpt;
89 pj_pool_t *pool;
90 pjmedia_port *file_port;
91 pjmedia_snd_port *snd_port;
92 char tmp[10];
93 pj_status_t status;
94
95
Benny Prijono8befd9f2006-05-13 22:46:23 +000096 if (argc != 2) {
97 puts("Error: filename required");
98 puts(desc);
99 return 1;
100 }
Benny Prijono15953012006-04-27 22:37:08 +0000101
102
Benny Prijonocbc1c472006-03-19 00:50:23 +0000103 /* Must init PJLIB first: */
104 status = pj_init();
105 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
106
107 /* Must create a pool factory before we can allocate any memory. */
108 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
109
110 /*
111 * Initialize media endpoint.
112 * This will implicitly initialize PJMEDIA too.
113 */
Benny Prijono275fd682006-03-22 11:59:11 +0000114 status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
Benny Prijonocbc1c472006-03-19 00:50:23 +0000115 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
116
117 /* Create memory pool for our file player */
118 pool = pj_pool_create( &cp.factory, /* pool factory */
119 "wav", /* pool name. */
120 4000, /* init size */
121 4000, /* increment size */
122 NULL /* callback on error */
123 );
124
125 /* Create file media port from the WAV file */
Benny Prijono15953012006-04-27 22:37:08 +0000126 status = pjmedia_wav_player_port_create( pool, /* memory pool */
Benny Prijonocbc1c472006-03-19 00:50:23 +0000127 argv[1], /* file to play */
Benny Prijono15953012006-04-27 22:37:08 +0000128 20, /* ptime. */
Benny Prijonocbc1c472006-03-19 00:50:23 +0000129 0, /* flags */
130 0, /* default buffer */
Benny Prijonocbc1c472006-03-19 00:50:23 +0000131 &file_port/* returned port */
132 );
133 if (status != PJ_SUCCESS) {
134 app_perror(THIS_FILE, "Unable to use WAV file", status);
135 return 1;
136 }
137
138 /* Create sound player port. */
139 status = pjmedia_snd_port_create_player(
140 pool, /* pool */
141 -1, /* use default dev. */
Benny Prijono15953012006-04-27 22:37:08 +0000142 file_port->info.clock_rate, /* clock rate. */
Benny Prijonocbc1c472006-03-19 00:50:23 +0000143 file_port->info.channel_count, /* # of channels. */
144 file_port->info.samples_per_frame, /* samples per frame. */
145 file_port->info.bits_per_sample, /* bits per sample. */
146 0, /* options */
147 &snd_port /* returned port */
148 );
149 if (status != PJ_SUCCESS) {
150 app_perror(THIS_FILE, "Unable to open sound device", status);
151 return 1;
152 }
153
154 /* Connect file port to the sound player.
155 * Stream playing will commence immediately.
156 */
157 status = pjmedia_snd_port_connect( snd_port, file_port);
158 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
159
160
161
162 /*
163 * File should be playing and looping now, using sound device's thread.
164 */
165
166
167 /* Sleep to allow log messages to flush */
168 pj_thread_sleep(100);
169
170
171 printf("Playing %s..\n", argv[1]);
172 puts("");
173 puts("Press <ENTER> to stop playing and quit");
174
Benny Prijono32d267b2009-01-01 22:08:21 +0000175 if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
176 puts("EOF while reading stdin, will quit now..");
177 }
Benny Prijonocbc1c472006-03-19 00:50:23 +0000178
179
180 /* Start deinitialization: */
181
Benny Prijono4abeb9b2007-02-17 19:34:46 +0000182 /* Disconnect sound port from file port */
183 status = pjmedia_snd_port_disconnect(snd_port);
184 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
185
186 /* Without this sleep, Windows/DirectSound will repeteadly
187 * play the last frame during destroy.
188 */
189 pj_thread_sleep(100);
190
Benny Prijonocbc1c472006-03-19 00:50:23 +0000191 /* Destroy sound device */
192 status = pjmedia_snd_port_destroy( snd_port );
193 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
194
195
196 /* Destroy file port */
197 status = pjmedia_port_destroy( file_port );
198 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
199
200
201 /* Release application pool */
202 pj_pool_release( pool );
203
204 /* Destroy media endpoint. */
205 pjmedia_endpt_destroy( med_endpt );
206
207 /* Destroy pool factory */
208 pj_caching_pool_destroy( &cp );
209
Benny Prijonoaf1bb1e2006-11-21 12:39:31 +0000210 /* Shutdown PJLIB */
211 pj_shutdown();
212
Benny Prijonocbc1c472006-03-19 00:50:23 +0000213
214 /* Done. */
215 return 0;
216}
Benny Prijonobf13fee2006-04-20 11:13:32 +0000217