1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#include <sys/types.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "conf.h"
#include "wav.h"
/*
* max data of a .wav file. The total file size must be smaller than
* 2^31, and we also have to leave some space for the headers (around 40
* bytes)
*/
#define WAV_DATAMAX (0x7fff0000)
struct fileops wav_ops = {
"wav",
sizeof(struct wav),
wav_close,
wav_read,
wav_write,
NULL, /* start */
NULL, /* stop */
pipe_nfds,
pipe_pollfd,
pipe_revents
};
struct wav *
wav_new_in(struct fileops *ops, int fd, char *name,
struct aparams *par, unsigned hdr)
{
struct wav *f;
f = (struct wav *)pipe_new(ops, fd, name);
if (f == NULL)
return NULL;
if (hdr == HDR_WAV) {
if (!wav_readhdr(f->pipe.fd, par, &f->rbytes))
exit(1);
f->hpar = *par;
} else
f->rbytes = -1;
f->hdr = 0;
return f;
}
struct wav *
wav_new_out(struct fileops *ops, int fd, char *name,
struct aparams *par, unsigned hdr)
{
struct wav *f;
f = (struct wav *)pipe_new(ops, fd, name);
if (f == NULL)
return NULL;
if (hdr == HDR_WAV) {
par->le = 1;
par->sig = (par->bits <= 8) ? 0 : 1;
par->bps = (par->bits + 7) / 8;
if (!wav_writehdr(f->pipe.fd, par))
exit(1);
f->hpar = *par;
f->wbytes = WAV_DATAMAX;
} else
f->wbytes = -1;
f->hdr = hdr;
return f;
}
unsigned
wav_read(struct file *file, unsigned char *data, unsigned count)
{
struct wav *f = (struct wav *)file;
unsigned n;
if (f->rbytes >= 0 && count > f->rbytes) {
count = f->rbytes; /* file->rbytes fits in count */
if (count == 0) {
DPRINTFN(2, "wav_read: %s: complete\n", f->pipe.file.name);
file_eof(&f->pipe.file);
return 0;
}
}
n = pipe_read(file, data, count);
if (f->rbytes >= 0)
f->rbytes -= n;
return n;
}
unsigned
wav_write(struct file *file, unsigned char *data, unsigned count)
{
struct wav *f = (struct wav *)file;
unsigned n;
if (f->wbytes >= 0 && count > f->wbytes) {
count = f->wbytes; /* wbytes fits in count */
if (count == 0) {
DPRINTFN(2, "wav_write: %s: complete\n",
f->pipe.file.name);
file_hup(&f->pipe.file);
return 0;
}
}
n = pipe_write(file, data, count);
if (f->wbytes >= 0)
f->wbytes -= n;
return n;
}
void
wav_close(struct file *file)
{
struct wav *f = (struct wav *)file;
if (f->hdr == HDR_WAV)
wav_writehdr(f->pipe.fd, &f->hpar);
pipe_close(file);
}
|