2
mediastreamer2 library - modular sound and video processing and streaming
3
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
5
This program is free software; you can redistribute it and/or
6
modify it under the terms of the GNU General Public License
7
as published by the Free Software Foundation; either version 2
8
of the License, or (at your option) any later version.
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.
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.
20
#include "mediastreamer2/msfileplayer.h"
21
#include "mediastreamer2/waveheader.h"
22
#include "mediastreamer2/msticker.h"
25
static int player_close(MSFilter *f, void *arg);
44
typedef struct _PlayerData PlayerData;
46
static void player_init(MSFilter *f){
47
PlayerData *d=ms_new(PlayerData,1);
54
d->loop_after=-1; /*by default, don't loop*/
59
static int read_wav_header(PlayerData *d){
61
if (read(d->fd,&wav,sizeof(wav))!=sizeof(wav)){
62
ms_warning("Could not read wav header");
65
if (0!=strncmp(wav.riff_chunk.riff, "RIFF", 4) || 0!=strncmp(wav.riff_chunk.wave, "WAVE", 4)){
66
ms_warning("Wrong wav header: (default rate/channel -> %i:%i)", d->rate, d->nchannels);
69
d->rate=wave_header_get_rate(&wav);
70
d->nchannels=wave_header_get_channel(&wav);
72
#ifdef WORDS_BIGENDIAN
73
if (wave_header_get_bpsmpl(&wav)==wave_header_get_channel(&wav) * 2)
79
static int player_open(MSFilter *f, void *arg){
80
PlayerData *d=(PlayerData*)f->data;
82
const char *file=(const char*)arg;
87
if ((fd=open(file,O_RDONLY))==-1){
88
ms_warning("Failed to open %s",file);
93
if (strstr(file,".wav")!=NULL) read_wav_header(d);
94
ms_message("%s opened: rate=%i,channel=%i",file,d->rate,d->nchannels);
98
static int player_start(MSFilter *f, void *arg){
99
PlayerData *d=(PlayerData*)f->data;
100
if (d->state==STOPPED)
105
static int player_stop(MSFilter *f, void *arg){
106
PlayerData *d=(PlayerData*)f->data;
108
if (d->state==STARTED){
110
lseek(d->fd,d->hsize,SEEK_SET);
116
static int player_close(MSFilter *f, void *arg){
117
PlayerData *d=(PlayerData*)f->data;
119
if (d->fd>=0) close(d->fd);
125
static void player_uninit(MSFilter *f){
126
PlayerData *d=(PlayerData*)f->data;
127
if (d->fd>=0) player_close(f,NULL);
131
static void swap_bytes(unsigned char *bytes, int len){
141
static void player_process(MSFilter *f){
142
PlayerData *d=(PlayerData*)f->data;
143
int bytes=2*(f->ticker->interval*d->rate*d->nchannels)/1000;
145
if (d->state==STARTED){
147
mblk_t *om=allocb(bytes,0);
148
if (d->pause_time>0){
150
memset(om->b_wptr,0,bytes);
151
d->pause_time-=f->ticker->interval;
153
err=read(d->fd,om->b_wptr,bytes);
154
if (d->swap) swap_bytes(om->b_wptr,bytes);
159
ms_queue_put(f->outputs[0],om);
162
ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);
163
if (d->loop_after>=0){
164
lseek(d->fd,d->hsize,SEEK_SET);
165
d->pause_time=d->loop_after;
166
}else d->state=STOPPED;
169
ms_warning("Fail to read %i bytes: %s",bytes,strerror(errno));
175
static int player_get_sr(MSFilter *f, void*arg){
176
PlayerData *d=(PlayerData*)f->data;
177
*((int*)arg)=d->rate;
181
static int player_loop(MSFilter *f, void *arg){
182
PlayerData *d=(PlayerData*)f->data;
183
d->loop_after=*((int*)arg);
187
static int player_eof(MSFilter *f, void *arg){
188
PlayerData *d=(PlayerData*)f->data;
189
if (d->fd<0 && d->state==CLOSED)
190
*((int*)arg) = TRUE; /* 1 */
192
*((int*)arg) = FALSE; /* 0 */
196
static int player_get_nch(MSFilter *f, void *arg){
197
PlayerData *d=(PlayerData*)f->data;
198
*((int*)arg)=d->nchannels;
202
static MSFilterMethod player_methods[]={
203
{ MS_FILE_PLAYER_OPEN, player_open },
204
{ MS_FILE_PLAYER_START, player_start },
205
{ MS_FILE_PLAYER_STOP, player_stop },
206
{ MS_FILE_PLAYER_CLOSE, player_close },
207
{ MS_FILTER_GET_SAMPLE_RATE, player_get_sr},
208
{ MS_FILTER_GET_NCHANNELS, player_get_nch },
209
{ MS_FILE_PLAYER_LOOP, player_loop },
210
{ MS_FILE_PLAYER_DONE, player_eof },
216
MSFilterDesc ms_file_player_desc={
219
"Raw files and wav reader",
234
MSFilterDesc ms_file_player_desc={
235
.id=MS_FILE_PLAYER_ID,
236
.name="MSFilePlayer",
237
.text="Raw files and wav reader",
238
.category=MS_FILTER_OTHER,
242
.process=player_process,
243
.uninit=player_uninit,
244
.methods=player_methods
249
MS_FILTER_DESC_EXPORT(ms_file_player_desc)