1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <tinyalsa/pcm.h>
5 
read_frames(void ** frames)6 static size_t read_frames(void **frames)
7 {
8     unsigned int card = 0;
9     unsigned int device = 0;
10     int flags = PCM_IN;
11 
12     const struct pcm_config config = {
13         .channels = 2,
14         .rate = 48000,
15         .format = PCM_FORMAT_S32_LE,
16         .period_size = 1024,
17         .period_count = 2,
18         .start_threshold = 1024,
19         .silence_threshold = 1024 * 2,
20         .stop_threshold = 1024 * 2
21     };
22 
23     struct pcm *pcm = pcm_open(card, device, flags, &config);
24     if (pcm == NULL) {
25         fprintf(stderr, "failed to allocate memory for PCM\n");
26         return 0;
27     } else if (!pcm_is_ready(pcm)){
28         pcm_close(pcm);
29         fprintf(stderr, "failed to open PCM\n");
30         return 0;
31     }
32 
33     unsigned int frame_size = pcm_frames_to_bytes(pcm, 1);
34     unsigned int frames_per_sec = pcm_get_rate(pcm);
35 
36     *frames = malloc(frame_size * frames_per_sec);
37     if (*frames == NULL) {
38         fprintf(stderr, "failed to allocate frames\n");
39         pcm_close(pcm);
40         return 0;
41     }
42 
43     int read_count = pcm_readi(pcm, *frames, frames_per_sec);
44 
45     size_t byte_count = pcm_frames_to_bytes(pcm, read_count);
46 
47     pcm_close(pcm);
48 
49     return byte_count;
50 }
51 
write_file(const void * frames,size_t size)52 static int write_file(const void *frames, size_t size)
53 {
54     FILE *output_file = fopen("audio.raw", "wb");
55     if (output_file == NULL) {
56         perror("failed to open 'audio.raw' for writing");
57         return EXIT_FAILURE;
58     }
59     fwrite(frames, 1, size, output_file);
60     fclose(output_file);
61     return 0;
62 }
63 
main(void)64 int main(void)
65 {
66     void *frames = NULL;
67     size_t size = 0;
68 
69     size = read_frames(&frames);
70     if (size == 0) {
71         return EXIT_FAILURE;
72     }
73 
74     if (write_file(frames, size) < 0) {
75         free(frames);
76         return EXIT_FAILURE;
77     }
78 
79     free(frames);
80 
81     return EXIT_SUCCESS;
82 }
83 
84