diff options
Diffstat (limited to 'src/plugins/wav_extractor.c')
-rw-r--r-- | src/plugins/wav_extractor.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/plugins/wav_extractor.c b/src/plugins/wav_extractor.c new file mode 100644 index 0000000..b50ebc2 --- /dev/null +++ b/src/plugins/wav_extractor.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (C) 2004, 2009 Vidyut Samanta and Christian Grothoff | ||
4 | |||
5 | libextractor is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | libextractor is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with libextractor; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | |||
20 | This code was based on bitcollider 0.6.0 | ||
21 | (PD) 2004 The Bitzi Corporation | ||
22 | http://bitzi.com/ | ||
23 | (PD) 2001 The Bitzi Corporation | ||
24 | Please see file COPYING or http://bitzi.com/publicdomain | ||
25 | for more info. | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include "platform.h" | ||
30 | #include "extractor.h" | ||
31 | |||
32 | #if BIG_ENDIAN_HOST | ||
33 | static short | ||
34 | toLittleEndian16 (short in) | ||
35 | { | ||
36 | char *ptr = (char *) ∈ | ||
37 | |||
38 | return ((ptr[1] & 0xFF) << 8) | (ptr[0] & 0xFF); | ||
39 | } | ||
40 | |||
41 | static unsigned int | ||
42 | toLittleEndian32 (unsigned int in) | ||
43 | { | ||
44 | char *ptr = (char *) ∈ | ||
45 | |||
46 | return ((ptr[3] & 0xFF) << 24) | ((ptr[2] & 0xFF) << 16) | ((ptr[1] & 0xFF) | ||
47 | << 8) | (ptr[0] | ||
48 | & | ||
49 | 0xFF); | ||
50 | } | ||
51 | #endif | ||
52 | |||
53 | |||
54 | /* | ||
55 | 16 4 bytes 0x00000010 // Length of the fmt data (16 bytes) | ||
56 | 20 2 bytes 0x0001 // Format tag: 1 = PCM | ||
57 | 22 2 bytes <channels> // Channels: 1 = mono, 2 = stereo | ||
58 | 24 4 bytes <sample rate> // Samples per second: e.g., 44100 | ||
59 | */ | ||
60 | int | ||
61 | EXTRACTOR_wav_extract (const unsigned char *buf, | ||
62 | size_t bufLen, | ||
63 | EXTRACTOR_MetaDataProcessor proc, | ||
64 | void *proc_cls, | ||
65 | const char *options) | ||
66 | { | ||
67 | unsigned short channels; | ||
68 | unsigned short sampleSize; | ||
69 | unsigned int sampleRate; | ||
70 | unsigned int dataLen; | ||
71 | unsigned int samples; | ||
72 | char scratch[256]; | ||
73 | |||
74 | if ((bufLen < 44) || | ||
75 | (buf[0] != 'R' || buf[1] != 'I' || | ||
76 | buf[2] != 'F' || buf[3] != 'F' || | ||
77 | buf[8] != 'W' || buf[9] != 'A' || | ||
78 | buf[10] != 'V' || buf[11] != 'E' || | ||
79 | buf[12] != 'f' || buf[13] != 'm' || buf[14] != 't' || buf[15] != ' ')) | ||
80 | return 0; /* not a WAV file */ | ||
81 | |||
82 | channels = *((unsigned short *) &buf[22]); | ||
83 | sampleRate = *((unsigned int *) &buf[24]); | ||
84 | sampleSize = *((unsigned short *) &buf[34]); | ||
85 | dataLen = *((unsigned int *) &buf[40]); | ||
86 | |||
87 | #if BIG_ENDIAN_HOST | ||
88 | channels = toLittleEndian16 (channels); | ||
89 | sampleSize = toLittleEndian16 (sampleSize); | ||
90 | sampleRate = toLittleEndian32 (sampleRate); | ||
91 | dataLen = toLittleEndian32 (dataLen); | ||
92 | #endif | ||
93 | |||
94 | if (sampleSize != 8 && sampleSize != 16) | ||
95 | return 0; /* invalid sample size found in wav file */ | ||
96 | if (channels == 0) | ||
97 | return 0; /* invalid channels value -- avoid division by 0! */ | ||
98 | samples = dataLen / (channels * (sampleSize >> 3)); | ||
99 | |||
100 | snprintf (scratch, | ||
101 | sizeof (scratch), | ||
102 | "%u ms, %d Hz, %s", | ||
103 | (samples < sampleRate) | ||
104 | ? (samples * 1000 / sampleRate) | ||
105 | : (samples / sampleRate) * 1000, | ||
106 | sampleRate, channels == 1 ? _("mono") : _("stereo")); | ||
107 | if (0 != proc (proc_cls, | ||
108 | "wav", | ||
109 | EXTRACTOR_METATYPE_RESOURCE_TYPE, | ||
110 | EXTRACTOR_METAFORMAT_UTF8, | ||
111 | "text/plain", | ||
112 | scratch, | ||
113 | strlen (scratch) +1)) | ||
114 | return 1; | ||
115 | if (0 != proc (proc_cls, | ||
116 | "wav", | ||
117 | EXTRACTOR_METATYPE_MIMETYPE, | ||
118 | EXTRACTOR_METAFORMAT_UTF8, | ||
119 | "text/plain", | ||
120 | "audio/x-wav", | ||
121 | strlen ("audio/x-wav") +1)) | ||
122 | return 1; | ||
123 | return 0; | ||
124 | } | ||