libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

wav_extractor.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2004, 2009, 2012 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 3, 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., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, 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  * @file plugins/wav_extractor.c
29  * @brief plugin to support WAV files
30  * @author Christian Grothoff
31  */
32 
33 #include "platform.h"
34 #include "extractor.h"
35 
36 
37 #if BIG_ENDIAN_HOST
38 static uint16_t
39 little_endian_to_host16 (uint16_t in)
40 {
41  unsigned char *ptr = (unsigned char *) ∈
42 
43  return ((ptr[1] & 0xFF) << 8) | (ptr[0] & 0xFF);
44 }
45 
46 
47 static uint32_t
48 little_endian_to_host32 (uint32_t in)
49 {
50  unsigned char *ptr = (unsigned char *) &in;
51 
52  return ((ptr[3] & 0xFF) << 24) | ((ptr[2] & 0xFF) << 16)
53  | ((ptr[1] & 0xFF) << 8) | (ptr[0] & 0xFF);
54 }
55 
56 
57 #endif
58 
59 
60 /**
61  * Extract information from WAV files.
62  *
63  * @param ec extraction context
64  *
65  * @detail
66  * A WAV header looks as follows:
67  *
68  * Offset Value meaning
69  * 16 4 bytes 0x00000010 // Length of the fmt data (16 bytes)
70  * 20 2 bytes 0x0001 // Format tag: 1 = PCM
71  * 22 2 bytes <channels> // Channels: 1 = mono, 2 = stereo
72  * 24 4 bytes <sample rate> // Samples per second: e.g., 44100
73  */
74 void
76 {
77  void *data;
78  const unsigned char *buf;
79  uint16_t channels;
80  uint16_t sample_size;
81  uint32_t sample_rate;
82  uint32_t data_len;
83  uint32_t samples;
84  char scratch[256];
85 
86  if (44 >
87  ec->read (ec->cls, &data, 44))
88  return;
89  buf = data;
90  if (((buf[0] != 'R') || (buf[1] != 'I') ||
91  (buf[2] != 'F') || (buf[3] != 'F') ||
92  (buf[8] != 'W') || (buf[9] != 'A') ||
93  (buf[10] != 'V') || (buf[11] != 'E') ||
94  (buf[12] != 'f') || (buf[13] != 'm') || (buf[14] != 't') || (buf[15] !=
95  ' ') ))
96  return; /* not a WAV file */
97 
98  channels = *((uint16_t *) &buf[22]);
99  sample_rate = *((uint32_t *) &buf[24]);
100  sample_size = *((uint16_t *) &buf[34]);
101  data_len = *((uint32_t *) &buf[40]);
102 
103 #if BIG_ENDIAN_HOST
104  channels = little_endian_to_host16 (channels);
105  sample_size = little_endian_to_host16 (sample_size);
106  sample_rate = little_endian_to_host32 (sample_rate);
107  data_len = little_endian_to_host32 (data_len);
108 #endif
109 
110  if ( (8 != sample_size) &&
111  (16 != sample_size) )
112  return; /* invalid sample size found in wav file */
113  if (0 == channels)
114  return; /* invalid channels value -- avoid division by 0! */
115  if (0 == sample_rate)
116  return; /* invalid sample_rate */
117  samples = data_len / (channels * (sample_size >> 3));
118 
119  snprintf (scratch,
120  sizeof (scratch),
121  "%u ms, %d Hz, %s",
122  (samples < sample_rate)
123  ? (samples * 1000 / sample_rate)
124  : (samples / sample_rate) * 1000,
125  sample_rate, (1 == channels) ? _ ("mono") : _ ("stereo"));
126  if (0 != ec->proc (ec->cls,
127  "wav",
130  "text/plain",
131  scratch,
132  strlen (scratch) + 1))
133  return;
134  if (0 != ec->proc (ec->cls,
135  "wav",
138  "text/plain",
139  "audio/x-wav",
140  strlen ("audio/x-wav") + 1))
141  return;
142 }
143 
144 
145 /* end of wav_extractor.c */
@ EXTRACTOR_METAFORMAT_UTF8
Definition: extractor.h:102
@ EXTRACTOR_METATYPE_RESOURCE_TYPE
Definition: extractor.h:233
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
plaform specifics
#define _(a)
Definition: platform.h:32
EXTRACTOR_MetaDataProcessor proc
Definition: extractor.h:525
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494
void EXTRACTOR_wav_extract_method(struct EXTRACTOR_ExtractContext *ec)
Definition: wav_extractor.c:75