diff options
Diffstat (limited to 'apps/metadata/wave.c')
-rw-r--r-- | apps/metadata/wave.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c new file mode 100644 index 0000000000..d29f9f5363 --- /dev/null +++ b/apps/metadata/wave.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdio.h> | ||
20 | #include <string.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <ctype.h> | ||
23 | #include <inttypes.h> | ||
24 | |||
25 | #include "system.h" | ||
26 | #include "id3.h" | ||
27 | #include "metadata_common.h" | ||
28 | |||
29 | bool get_wave_metadata(int fd, struct mp3entry* id3) | ||
30 | { | ||
31 | /* Use the trackname part of the id3 structure as a temporary buffer */ | ||
32 | unsigned char* buf = (unsigned char *)id3->path; | ||
33 | unsigned long totalsamples = 0; | ||
34 | unsigned long channels = 0; | ||
35 | unsigned long bitspersample = 0; | ||
36 | unsigned long numbytes = 0; | ||
37 | int read_bytes; | ||
38 | int i; | ||
39 | |||
40 | /* get RIFF chunk header */ | ||
41 | if ((lseek(fd, 0, SEEK_SET) < 0) | ||
42 | || ((read_bytes = read(fd, buf, 12)) < 12)) | ||
43 | { | ||
44 | return false; | ||
45 | } | ||
46 | |||
47 | if ((memcmp(buf, "RIFF",4) != 0) | ||
48 | || (memcmp(&buf[8], "WAVE", 4) !=0 )) | ||
49 | { | ||
50 | return false; | ||
51 | } | ||
52 | |||
53 | /* iterate over WAVE chunks until 'data' chunk */ | ||
54 | while (true) | ||
55 | { | ||
56 | /* get chunk header */ | ||
57 | if ((read_bytes = read(fd, buf, 8)) < 8) | ||
58 | return false; | ||
59 | |||
60 | /* chunkSize */ | ||
61 | i = get_long_le(&buf[4]); | ||
62 | |||
63 | if (memcmp(buf, "fmt ", 4) == 0) | ||
64 | { | ||
65 | /* get rest of chunk */ | ||
66 | if ((read_bytes = read(fd, buf, 16)) < 16) | ||
67 | return false; | ||
68 | |||
69 | i -= 16; | ||
70 | |||
71 | /* skipping wFormatTag */ | ||
72 | /* wChannels */ | ||
73 | channels = buf[2] | (buf[3] << 8); | ||
74 | /* dwSamplesPerSec */ | ||
75 | id3->frequency = get_long_le(&buf[4]); | ||
76 | /* dwAvgBytesPerSec */ | ||
77 | id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000; | ||
78 | /* skipping wBlockAlign */ | ||
79 | /* wBitsPerSample */ | ||
80 | bitspersample = buf[14] | (buf[15] << 8); | ||
81 | } | ||
82 | else if (memcmp(buf, "data", 4) == 0) | ||
83 | { | ||
84 | numbytes = i; | ||
85 | break; | ||
86 | } | ||
87 | else if (memcmp(buf, "fact", 4) == 0) | ||
88 | { | ||
89 | /* dwSampleLength */ | ||
90 | if (i >= 4) | ||
91 | { | ||
92 | /* get rest of chunk */ | ||
93 | if ((read_bytes = read(fd, buf, 4)) < 4) | ||
94 | return false; | ||
95 | |||
96 | i -= 4; | ||
97 | totalsamples = get_long_le(buf); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | /* seek to next chunk (even chunk sizes must be padded) */ | ||
102 | if (i & 0x01) | ||
103 | i++; | ||
104 | |||
105 | if(lseek(fd, i, SEEK_CUR) < 0) | ||
106 | return false; | ||
107 | } | ||
108 | |||
109 | if ((numbytes == 0) || (channels == 0)) | ||
110 | { | ||
111 | return false; | ||
112 | } | ||
113 | |||
114 | if (totalsamples == 0) | ||
115 | { | ||
116 | /* for PCM only */ | ||
117 | totalsamples = numbytes | ||
118 | / ((((bitspersample - 1) / 8) + 1) * channels); | ||
119 | } | ||
120 | |||
121 | id3->vbr = false; /* All WAV files are CBR */ | ||
122 | id3->filesize = filesize(fd); | ||
123 | |||
124 | /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */ | ||
125 | id3->length = ((int64_t) totalsamples * 1000) / id3->frequency; | ||
126 | |||
127 | return true; | ||
128 | } | ||