ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
Avr.php
Go to the documentation of this file.
1 <?php
2 
3 namespace GetId3\Module\Audio;
4 
7 
10 // available at http://getid3.sourceforge.net //
11 // or http://www.getid3.org //
13 // See readme.txt for more details //
15 // //
16 // module.audio.avr.php //
17 // module for analyzing AVR Audio files //
18 // dependencies: NONE //
19 // ///
21 
29 class Avr extends BaseHandler
30 {
31  public function analyze()
32  {
33  $info = &$this->getid3->info;
34 
35  // http://cui.unige.ch/OSG/info/AudioFormats/ap11.html
36  // http://www.btinternet.com/~AnthonyJ/Atari/programming/avr_format.html
37  // offset type length name comments
38  // ---------------------------------------------------------------------
39  // 0 char 4 ID format ID == "2BIT"
40  // 4 char 8 name sample name (unused space filled with 0)
41  // 12 short 1 mono/stereo 0=mono, -1 (0xFFFF)=stereo
42  // With stereo, samples are alternated,
43  // the first voice is the left :
44  // (LRLRLRLRLRLRLRLRLR...)
45  // 14 short 1 resolution 8, 12 or 16 (bits)
46  // 16 short 1 signed or not 0=unsigned, -1 (0xFFFF)=signed
47  // 18 short 1 loop or not 0=no loop, -1 (0xFFFF)=loop on
48  // 20 short 1 MIDI note 0xFFnn, where 0 <= nn <= 127
49  // 0xFFFF means "no MIDI note defined"
50  // 22 byte 1 Replay speed Frequence in the Replay software
51  // 0=5.485 Khz, 1=8.084 Khz, 2=10.971 Khz,
52  // 3=16.168 Khz, 4=21.942 Khz, 5=32.336 Khz
53  // 6=43.885 Khz, 7=47.261 Khz
54  // -1 (0xFF)=no defined Frequence
55  // 23 byte 3 sample rate in Hertz
56  // 26 long 1 size in bytes (2 * bytes in stereo)
57  // 30 long 1 loop begin 0 for no loop
58  // 34 long 1 loop size equal to 'size' for no loop
59  // 38 short 2 Reserved, MIDI keyboard split */
60  // 40 short 2 Reserved, sample compression */
61  // 42 short 2 Reserved */
62  // 44 char 20; Additional filename space, used if (name[7] != 0)
63  // 64 byte 64 user data
64  // 128 bytes ? sample data (12 bits samples are coded on 16 bits:
65  // 0000 xxxx xxxx xxxx)
66  // ---------------------------------------------------------------------
67  // Note that all values are in motorola (big-endian) format, and that long is
68  // assumed to be 4 bytes, and short 2 bytes.
69  // When reading the samples, you should handle both signed and unsigned data,
70  // and be prepared to convert 16->8 bit, or mono->stereo if needed. To convert
71  // 8-bit data between signed/unsigned just add 127 to the sample values.
72  // Simularly for 16-bit data you should add 32769
73 
74  $info['fileformat'] = 'avr';
75 
76  fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
77  $AVRheader = fread($this->getid3->fp, 128);
78 
79  $info['avr']['raw']['magic'] = substr($AVRheader, 0, 4);
80  $magic = '2BIT';
81  if ($info['avr']['raw']['magic'] != $magic) {
82  $info['error'][] = 'Expecting "' . Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . Helper::PrintHexBytes($info['avr']['raw']['magic']) . '"';
83  unset($info['fileformat']);
84  unset($info['avr']);
85 
86  return false;
87  }
88  $info['avdataoffset'] += 128;
89 
90  $info['avr']['sample_name'] = rtrim(substr($AVRheader, 4, 8));
91  $info['avr']['raw']['mono'] = Helper::BigEndian2Int(substr($AVRheader,
92  12,
93  2));
94  $info['avr']['bits_per_sample'] = Helper::BigEndian2Int(substr($AVRheader,
95  14,
96  2));
97  $info['avr']['raw']['signed'] = Helper::BigEndian2Int(substr($AVRheader,
98  16,
99  2));
100  $info['avr']['raw']['loop'] = Helper::BigEndian2Int(substr($AVRheader,
101  18,
102  2));
103  $info['avr']['raw']['midi'] = Helper::BigEndian2Int(substr($AVRheader,
104  20,
105  2));
106  $info['avr']['raw']['replay_freq'] = Helper::BigEndian2Int(substr($AVRheader,
107  22,
108  1));
109  $info['avr']['sample_rate'] = Helper::BigEndian2Int(substr($AVRheader,
110  23,
111  3));
112  $info['avr']['sample_length'] = Helper::BigEndian2Int(substr($AVRheader,
113  26,
114  4));
115  $info['avr']['loop_start'] = Helper::BigEndian2Int(substr($AVRheader,
116  30,
117  4));
118  $info['avr']['loop_end'] = Helper::BigEndian2Int(substr($AVRheader,
119  34, 4));
120  $info['avr']['midi_split'] = Helper::BigEndian2Int(substr($AVRheader,
121  38,
122  2));
123  $info['avr']['sample_compression'] = Helper::BigEndian2Int(substr($AVRheader,
124  40,
125  2));
126  $info['avr']['reserved'] = Helper::BigEndian2Int(substr($AVRheader,
127  42, 2));
128  $info['avr']['sample_name_extra'] = rtrim(substr($AVRheader, 44, 20));
129  $info['avr']['comment'] = rtrim(substr($AVRheader, 64, 64));
130 
131  $info['avr']['flags']['stereo'] = (($info['avr']['raw']['mono'] == 0) ? false : true);
132  $info['avr']['flags']['signed'] = (($info['avr']['raw']['signed'] == 0) ? false : true);
133  $info['avr']['flags']['loop'] = (($info['avr']['raw']['loop'] == 0) ? false : true);
134 
135  $info['avr']['midi_notes'] = array();
136  if (($info['avr']['raw']['midi'] & 0xFF00) != 0xFF00) {
137  $info['avr']['midi_notes'][] = ($info['avr']['raw']['midi'] & 0xFF00) >> 8;
138  }
139  if (($info['avr']['raw']['midi'] & 0x00FF) != 0x00FF) {
140  $info['avr']['midi_notes'][] = ($info['avr']['raw']['midi'] & 0x00FF);
141  }
142 
143  if (($info['avdataend'] - $info['avdataoffset']) != ($info['avr']['sample_length'] * (($info['avr']['bits_per_sample'] == 8) ? 1 : 2))) {
144  $info['warning'][] = 'Probable truncated file: expecting ' . ($info['avr']['sample_length'] * (($info['avr']['bits_per_sample'] == 8) ? 1 : 2)) . ' bytes of audio data, found ' . ($info['avdataend'] - $info['avdataoffset']);
145  }
146 
147  $info['audio']['dataformat'] = 'avr';
148  $info['audio']['lossless'] = true;
149  $info['audio']['bitrate_mode'] = 'cbr';
150  $info['audio']['bits_per_sample'] = $info['avr']['bits_per_sample'];
151  $info['audio']['sample_rate'] = $info['avr']['sample_rate'];
152  $info['audio']['channels'] = ($info['avr']['flags']['stereo'] ? 2 : 1);
153  $info['playtime_seconds'] = ($info['avr']['sample_length'] / $info['audio']['channels']) / $info['avr']['sample_rate'];
154  $info['audio']['bitrate'] = ($info['avr']['sample_length'] * (($info['avr']['bits_per_sample'] == 8) ? 8 : 16)) / $info['playtime_seconds'];
155 
156  return true;
157  }
158 }
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
Definition: Helper.php:36
GetId3() by James Heinrich info@getid3.org //.
Definition: BaseHandler.php:25
fseek($bytes, $whence=SEEK_SET)
$info
Definition: example_052.php:80
Create styles array
The data for the language used.
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: Helper.php:374
GetId3() by James Heinrich info@getid3.org //.
Definition: Avr.php:29