aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'tinyplay.c')
-rw-r--r--tinyplay.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/tinyplay.c b/tinyplay.c
new file mode 100644
index 0000000..2523e54
--- /dev/null
+++ b/tinyplay.c
@@ -0,0 +1,145 @@
1/* tinyplay.c
2**
3** Copyright 2011, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7** * Redistributions of source code must retain the above copyright
8** notice, this list of conditions and the following disclaimer.
9** * Redistributions in binary form must reproduce the above copyright
10** notice, this list of conditions and the following disclaimer in the
11** documentation and/or other materials provided with the distribution.
12** * Neither the name of The Android Open Source Project nor the names of
13** its contributors may be used to endorse or promote products derived
14** from this software without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26** DAMAGE.
27*/
28
29#include <tinyalsa/asoundlib.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <stdint.h>
33
34#define ID_RIFF 0x46464952
35#define ID_WAVE 0x45564157
36#define ID_FMT 0x20746d66
37#define ID_DATA 0x61746164
38
39#define FORMAT_PCM 1
40
41struct wav_header {
42 uint32_t riff_id;
43 uint32_t riff_sz;
44 uint32_t riff_fmt;
45 uint32_t fmt_id;
46 uint32_t fmt_sz;
47 uint16_t audio_format;
48 uint16_t num_channels;
49 uint32_t sample_rate;
50 uint32_t byte_rate;
51 uint16_t block_align;
52 uint16_t bits_per_sample;
53 uint32_t data_id;
54 uint32_t data_sz;
55};
56
57void play_sample(FILE *file, unsigned int channels, unsigned int rate,
58 unsigned int bits);
59
60int main(int argc, char **argv)
61{
62 FILE *file;
63 struct wav_header header;
64
65 if (argc != 2) {
66 fprintf(stderr, "Usage: %s <file.wav>\n", argv[0]);
67 return 1;
68 }
69
70 file = fopen(argv[1], "rb");
71 if (!file) {
72 fprintf(stderr, "Unable to open file '%s'\n", argv[1]);
73 return 1;
74 }
75
76 fread(&header, sizeof(struct wav_header), 1, file);
77
78 if ((header.riff_id != ID_RIFF) ||
79 (header.riff_fmt != ID_WAVE) ||
80 (header.fmt_id != ID_FMT) ||
81 (header.audio_format != FORMAT_PCM) ||
82 (header.fmt_sz != 16)) {
83 fprintf(stderr, "Error: '%s' is not a PCM riff/wave file\n", argv[1]);
84 fclose(file);
85 return 1;
86 }
87
88 play_sample(file, header.num_channels, header.sample_rate,
89 header.bits_per_sample);
90
91 fclose(file);
92
93 return 0;
94}
95
96void play_sample(FILE *file, unsigned int channels, unsigned int rate,
97 unsigned int bits)
98{
99 struct pcm_config config;
100 struct pcm *pcm;
101 char *buffer;
102 int size;
103 int num_read;
104
105 config.channels = channels;
106 config.rate = rate;
107 config.period_size = 1024;
108 config.period_count = 4;
109 if (bits == 32)
110 config.format = PCM_FORMAT_S32_LE;
111 else if (bits == 16)
112 config.format = PCM_FORMAT_S16_LE;
113
114 pcm = pcm_open(0, 0, PCM_OUT, &config);
115 if (!pcm || !pcm_is_ready(pcm)) {
116 fprintf(stderr, "Unable to open PCM device (%s)\n",
117 pcm_get_error(pcm));
118 return;
119 }
120
121 size = pcm_get_buffer_size(pcm);
122 buffer = malloc(size);
123 if (!buffer) {
124 fprintf(stderr, "Unable to allocate %d bytes\n", size);
125 free(buffer);
126 pcm_close(pcm);
127 return;
128 }
129
130 printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
131
132 do {
133 num_read = fread(buffer, 1, size, file);
134 if (num_read > 0) {
135 if (pcm_write(pcm, buffer, num_read)) {
136 fprintf(stderr, "Error playing sample\n");
137 break;
138 }
139 }
140 } while (num_read > 0);
141
142 free(buffer);
143 pcm_close(pcm);
144}
145