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