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