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.
22
#include "mediastreamer2/msfilerec.h"
23
#include "mediastreamer2/waveheader.h"
25
#if !defined(_WIN32_WCE)
26
#include <sys/types.h>
38
typedef struct RecState{
46
static void rec_init(MSFilter *f){
47
RecState *s=(RecState *)ms_new(RecState,1);
48
s->fd=INVALID_HANDLE_VALUE;
55
static void rec_process(MSFilter *f){
56
RecState *s=(RecState*)f->data;
59
while((m=ms_queue_get(f->inputs[0]))!=NULL){
61
ms_mutex_lock(&f->lock);
62
if (s->state==Started){
64
int len=it->b_wptr-it->b_rptr;
66
if ((err=WriteFile(s->fd,it->b_rptr,len, &byte_written, NULL))!=len){
69
#if !defined(_WIN32_WCE)
70
ms_warning("MSFileRec: fail to write %i bytes: %s",len,strerror(errno));
72
ms_warning("MSFileRec: fail to write %i bytes: %i",len,WSAGetLastError());
80
ms_mutex_unlock(&f->lock);
85
static void write_wav_header(int rate,int size, char *filename){
87
DWORD bytes_written=0;
90
MultiByteToWideChar(CP_UTF8, 0, filename, -1, wUnicode, 1024);
92
memcpy(&header.riff_chunk.riff,"RIFF",4);
93
header.riff_chunk.len=le_uint32(size+32);
94
memcpy(&header.riff_chunk.wave,"WAVE",4);
96
memcpy(&header.format_chunk.fmt,"fmt ",4);
97
header.format_chunk.len=le_uint32(0x10);
98
header.format_chunk.type=le_uint16(0x1);
99
header.format_chunk.channel=le_uint16(0x1);
100
header.format_chunk.rate=le_uint32(rate);
101
header.format_chunk.bps=le_uint32(rate*2);
102
header.format_chunk.blockalign=le_uint16(2);
103
header.format_chunk.bitpspl=le_uint16(16);
105
memcpy(&header.data_chunk.data,"data",4);
106
header.data_chunk.len=le_uint32(size);
108
/* TODO: replace with "lseek" equivalent for windows */
109
fd=CreateFile(wUnicode, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
110
if (fd==INVALID_HANDLE_VALUE){
111
#if !defined(_WIN32_WCE)
112
ms_warning("Cannot open %s: %s",filename,strerror(errno));
114
ms_warning("Cannot open %s: %i",filename,WSAGetLastError());
118
WriteFile(fd,&header,sizeof(header), &bytes_written, NULL);
119
if (bytes_written!=sizeof(header)){
120
ms_warning("Fail to write wav header.");
125
static int rec_open(MSFilter *f, void *arg){
126
wave_header_t header;
127
DWORD bytes_written=0;
129
RecState *s=(RecState*)f->data;
130
const char *filename=(const char*)arg;
131
WCHAR wUnicode[1024];
132
MultiByteToWideChar(CP_UTF8, 0, filename, -1, wUnicode, 1024);
134
ms_mutex_lock(&f->lock);
135
snprintf(s->filename, sizeof(s->filename), "%s", filename);
136
s->fd=CreateFile(wUnicode, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
137
if (s->fd==INVALID_HANDLE_VALUE){
138
#if !defined(_WIN32_WCE)
139
ms_warning("Cannot open %s: %s",filename,strerror(errno));
141
ms_warning("Cannot open %s: %i",filename,WSAGetLastError());
143
ms_mutex_unlock(&f->lock);
147
memset(&header ,0,sizeof(header));
148
WriteFile(s->fd,&header,sizeof(header), &bytes_written, NULL);
149
if (bytes_written!=sizeof(header)){
150
ms_warning("Fail to write wav header.");
154
ms_mutex_unlock(&f->lock);
158
static int rec_start(MSFilter *f, void *arg){
159
RecState *s=(RecState*)f->data;
160
ms_mutex_lock(&f->lock);
162
ms_mutex_unlock(&f->lock);
166
static int rec_stop(MSFilter *f, void *arg){
167
RecState *s=(RecState*)f->data;
168
ms_mutex_lock(&f->lock);
170
ms_mutex_unlock(&f->lock);
174
static int rec_close(MSFilter *f, void *arg){
175
RecState *s=(RecState*)f->data;
176
ms_mutex_lock(&f->lock);
178
if (s->fd!=INVALID_HANDLE_VALUE) {
180
write_wav_header(s->rate, s->size, s->filename);
181
s->fd=INVALID_HANDLE_VALUE;
184
ms_mutex_unlock(&f->lock);
188
static int rec_set_sr(MSFilter *f, void *arg){
189
RecState *s=(RecState*)f->data;
190
ms_mutex_lock(&f->lock);
191
s->rate=*((int*)arg);
192
ms_mutex_unlock(&f->lock);
196
static void rec_uninit(MSFilter *f){
197
RecState *s=(RecState*)f->data;
198
if (s->fd!=INVALID_HANDLE_VALUE) rec_close(f,NULL);
202
static MSFilterMethod rec_methods[]={
203
{ MS_FILTER_SET_SAMPLE_RATE, rec_set_sr },
204
{ MS_FILE_REC_OPEN , rec_open },
205
{ MS_FILE_REC_START , rec_start },
206
{ MS_FILE_REC_STOP , rec_stop },
207
{ MS_FILE_REC_CLOSE , rec_close },
213
MSFilterDesc ms_file_rec_desc={
216
N_("Wav file recorder"),
231
MSFilterDesc ms_file_rec_desc={
234
.text=N_("Wav file recorder"),
235
.category=MS_FILTER_OTHER,
239
.process=rec_process,
246
MS_FILTER_DESC_EXPORT(ms_file_rec_desc)