-
Notifications
You must be signed in to change notification settings - Fork 2
/
oss-record.c
95 lines (77 loc) · 2.27 KB
/
oss-record.c
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
/** Audio API Quick Start Guide: OSS: Record audio and pass to stdout
Link with -lm */
#include <sys/soundcard.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
int quit;
int abuf_create(int playback, void **data, int *buf_size, int *frame_size)
{
// Open device
int dsp;
const char *device_id = NULL;
if (device_id == NULL)
device_id = "/dev/dsp";
int flags = (playback) ? O_WRONLY : O_RDONLY;
assert(0 < (dsp = open(device_id, flags | O_EXCL, 0)));
// Set sample format
int format = AFMT_S16_LE;
assert(0 <= ioctl(dsp, SNDCTL_DSP_SETFMT, &format));
// Set channels
int channels = 2;
assert(0 <= ioctl(dsp, SNDCTL_DSP_CHANNELS, &channels));
// Set sample rate
int sample_rate = 44100;
assert(0 <= ioctl(dsp, SNDCTL_DSP_SPEED, &sample_rate));
fprintf(stderr, "Using format %u, sample rate %u, channels %u\n", format, sample_rate, channels);
audio_buf_info info = {};
// Set buffer length
if (playback)
assert(0 <= ioctl(dsp, SNDCTL_DSP_GETOSPACE, &info));
else
assert(0 <= ioctl(dsp, SNDCTL_DSP_GETISPACE, &info));
int buffer_length_msec = 500;
int frag_num = sample_rate * 16/8 * channels * buffer_length_msec / 1000 / info.fragsize;
int fr = (frag_num << 16) | (int)log2(info.fragsize); // buf_size = frag_num * 2^n
assert(0 <= ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &fr));
// Get buffer length
memset(&info, 0, sizeof(info));
if (playback)
assert(0 <= ioctl(dsp, SNDCTL_DSP_GETOSPACE, &info));
else
assert(0 <= ioctl(dsp, SNDCTL_DSP_GETISPACE, &info));
buffer_length_msec = info.fragstotal * info.fragsize * 1000 / (sample_rate * 16/8 * channels);
*buf_size = info.fragstotal * info.fragsize;
*frame_size = 16/8 * sample_rate * channels;
// Create buffer for audio data
*data = malloc(*buf_size);
return dsp;
}
void on_sigint()
{
quit = 1;
}
void main()
{
void *buf;
int buf_size, frame_size;
int dsp = abuf_create(0, &buf, &buf_size, &frame_size);
// Properly handle SIGINT from user
struct sigaction sa = {};
sa.sa_handler = on_sigint;
sigaction(SIGINT, &sa, NULL);
while (!quit) {
// Read audio data into our buffer
int n = read(dsp, buf, buf_size);
assert(n >= 0);
// Write to stdout
write(1, buf, n);
}
free(buf);
close(dsp);
}