1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <tinyalsa/pcm.h>
5 
file_size(FILE * file)6 static long int file_size(FILE * file)
7 {
8     if (fseek(file, 0, SEEK_END) < 0) {
9         return -1;
10     }
11     long int file_size = ftell(file);
12     if (fseek(file, 0, SEEK_SET) < 0) {
13         return -1;
14     }
15     return file_size;
16 }
17 
read_file(void ** frames)18 static size_t read_file(void ** frames){
19 
20     FILE * input_file = fopen("audio.raw", "rb");
21     if (input_file == NULL) {
22         perror("failed to open 'audio.raw' for writing");
23         return 0;
24     }
25 
26     long int size = file_size(input_file);
27     if (size < 0) {
28         perror("failed to get file size of 'audio.raw'");
29         fclose(input_file);
30         return 0;
31     }
32 
33     *frames = malloc(size);
34     if (*frames == NULL) {
35         fprintf(stderr, "failed to allocate frames\n");
36         fclose(input_file);
37         return 0;
38     }
39 
40     size = fread(*frames, 1, size, input_file);
41 
42     fclose(input_file);
43 
44     return size;
45 }
46 
write_frames(const void * frames,size_t byte_count)47 static int write_frames(const void * frames, size_t byte_count){
48 
49     unsigned int card = 0;
50     unsigned int device = 0;
51     int flags = PCM_OUT;
52 
53     const struct pcm_config config = {
54         .channels = 2,
55         .rate = 48000,
56         .format = PCM_FORMAT_S32_LE,
57         .period_size = 1024,
58         .period_count = 2,
59         .start_threshold = 1024,
60         .silence_threshold = 1024 * 2,
61         .stop_threshold = 1024 * 2
62     };
63 
64     struct pcm * pcm = pcm_open(card, device, flags, &config);
65     if (pcm == NULL) {
66         fprintf(stderr, "failed to allocate memory for PCM\n");
67         return -1;
68     } else if (!pcm_is_ready(pcm)){
69         pcm_close(pcm);
70         fprintf(stderr, "failed to open PCM\n");
71         return -1;
72     }
73 
74     unsigned int frame_count = pcm_bytes_to_frames(pcm, byte_count);
75 
76     int err = pcm_writei(pcm, frames, frame_count);
77     if (err < 0) {
78       printf("error: %s\n", pcm_get_error(pcm));
79     }
80 
81     pcm_close(pcm);
82 
83     return 0;
84 }
85 
main(void)86 int main(void)
87 {
88     void *frames;
89     size_t size;
90 
91     size = read_file(&frames);
92     if (size == 0) {
93         return EXIT_FAILURE;
94     }
95 
96     if (write_frames(frames, size) < 0) {
97         return EXIT_FAILURE;
98     }
99 
100     free(frames);
101     return EXIT_SUCCESS;
102 }
103 
104