]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/james-heinrich/getid3/getid3/module.audio.dsf.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / james-heinrich / getid3 / getid3 / module.audio.dsf.php
1 <?php
2 /////////////////////////////////////////////////////////////////
3 /// getID3() by James Heinrich <info@getid3.org>               //
4 //  available at http://getid3.sourceforge.net                 //
5 //            or http://www.getid3.org                         //
6 //          also https://github.com/JamesHeinrich/getID3       //
7 /////////////////////////////////////////////////////////////////
8 // See readme.txt for more details                             //
9 /////////////////////////////////////////////////////////////////
10 //                                                             //
11 // module.audio.dsf.php                                        //
12 // module for analyzing dsf/DSF Audio files                    //
13 // dependencies: module.tag.id3v2.php                          //
14 //                                                            ///
15 /////////////////////////////////////////////////////////////////
16
17 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
18
19 class getid3_dsf extends getid3_handler
20 {
21
22         public function Analyze() {
23                 $info = &$this->getid3->info;
24
25                 $info['fileformat']            = 'dsf';
26                 $info['audio']['dataformat']   = 'dsf';
27                 $info['audio']['lossless']     = true;
28                 $info['audio']['bitrate_mode'] = 'cbr';
29
30                 $this->fseek($info['avdataoffset']);
31                 $dsfheader = $this->fread(28 + 12);
32
33                 $headeroffset = 0;
34                 $info['dsf']['dsd']['magic'] = substr($dsfheader, $headeroffset, 4);
35                 $headeroffset += 4;
36                 $magic = 'DSD ';
37                 if ($info['dsf']['dsd']['magic'] != $magic) {
38                         $this->error('Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['dsf']['dsd']['magic']).'"');
39                         unset($info['fileformat']);
40                         unset($info['audio']);
41                         unset($info['dsf']);
42                         return false;
43                 }
44                 $info['dsf']['dsd']['dsd_chunk_size']     = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8)); // should be 28
45                 $headeroffset += 8;
46                 $info['dsf']['dsd']['dsf_file_size']      = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8));
47                 $headeroffset += 8;
48                 $info['dsf']['dsd']['meta_chunk_offset']  = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8));
49                 $headeroffset += 8;
50
51
52                 $info['dsf']['fmt']['magic'] = substr($dsfheader, $headeroffset, 4);
53                 $headeroffset += 4;
54                 $magic = 'fmt ';
55                 if ($info['dsf']['fmt']['magic'] != $magic) {
56                         $this->error('Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$headeroffset.', found "'.getid3_lib::PrintHexBytes($info['dsf']['fmt']['magic']).'"');
57                         return false;
58                 }
59                 $info['dsf']['fmt']['fmt_chunk_size']     = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8));  // usually 52 bytes
60                 $headeroffset += 8;
61                 $dsfheader .= $this->fread($info['dsf']['fmt']['fmt_chunk_size'] - 12 + 12);  // we have already read the entire DSD chunk, plus 12 bytes of FMT. We now want to read the size of FMT, plus 12 bytes into the next chunk to get magic and size.
62                 if (strlen($dsfheader) != ($info['dsf']['dsd']['dsd_chunk_size'] + $info['dsf']['fmt']['fmt_chunk_size'] + 12)) {
63                         $this->error('Expecting '.($info['dsf']['dsd']['dsd_chunk_size'] + $info['dsf']['fmt']['fmt_chunk_size']).' bytes header, found '.strlen($dsfheader).' bytes');
64                         return false;
65                 }
66                 $info['dsf']['fmt']['format_version']     = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));  // usually "1"
67                 $headeroffset += 4;
68                 $info['dsf']['fmt']['format_id']          = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));  // usually "0" = "DSD Raw"
69                 $headeroffset += 4;
70                 $info['dsf']['fmt']['channel_type_id']    = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));
71                 $headeroffset += 4;
72                 $info['dsf']['fmt']['channels']           = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));
73                 $headeroffset += 4;
74                 $info['dsf']['fmt']['sample_rate']        = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));
75                 $headeroffset += 4;
76                 $info['dsf']['fmt']['bits_per_sample']    = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));
77                 $headeroffset += 4;
78                 $info['dsf']['fmt']['sample_count']       = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8));
79                 $headeroffset += 8;
80                 $info['dsf']['fmt']['channel_block_size'] = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4));
81                 $headeroffset += 4;
82                 $info['dsf']['fmt']['reserved']           = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 4)); // zero-filled
83                 $headeroffset += 4;
84
85
86                 $info['dsf']['data']['magic'] = substr($dsfheader, $headeroffset, 4);
87                 $headeroffset += 4;
88                 $magic = 'data';
89                 if ($info['dsf']['data']['magic'] != $magic) {
90                         $this->error('Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$headeroffset.', found "'.getid3_lib::PrintHexBytes($info['dsf']['data']['magic']).'"');
91                         return false;
92                 }
93                 $info['dsf']['data']['data_chunk_size']    = getid3_lib::LittleEndian2Int(substr($dsfheader, $headeroffset, 8));
94                 $headeroffset += 8;
95                 $info['avdataoffset'] = $headeroffset;
96                 $info['avdataend']    = $info['avdataoffset'] + $info['dsf']['data']['data_chunk_size'];
97
98
99                 if ($info['dsf']['dsd']['meta_chunk_offset'] > 0) {
100                         $getid3_id3v2 = new getid3_id3v2($this->getid3);
101                         $getid3_id3v2->StartingOffset = $info['dsf']['dsd']['meta_chunk_offset'];
102                         $getid3_id3v2->Analyze();
103                         unset($getid3_id3v2);
104                 }
105
106
107                 $info['dsf']['fmt']['channel_type'] = $this->DSFchannelTypeLookup($info['dsf']['fmt']['channel_type_id']);
108                 $info['audio']['channelmode']       = $info['dsf']['fmt']['channel_type'];
109                 $info['audio']['bits_per_sample']   = $info['dsf']['fmt']['bits_per_sample'];
110                 $info['audio']['sample_rate']       = $info['dsf']['fmt']['sample_rate'];
111                 $info['audio']['channels']          = $info['dsf']['fmt']['channels'];
112                 $info['audio']['bitrate']           = $info['audio']['bits_per_sample'] * $info['audio']['sample_rate'] * $info['audio']['channels'];
113                 $info['playtime_seconds']           = ($info['dsf']['data']['data_chunk_size'] * 8) / $info['audio']['bitrate'];
114
115                 return true;
116         }
117
118
119         public static function DSFchannelTypeLookup($channel_type_id) {
120                 static $DSFchannelTypeLookup = array(
121                                           // interleaving order:
122                         1 => 'mono',      // 1: Mono
123                         2 => 'stereo',    // 1: Front-Left; 2: Front-Right
124                         3 => '3-channel', // 1: Front-Left; 2: Front-Right; 3: Center
125                         4 => 'quad',      // 1: Front-Left; 2: Front-Right; 3: Back-Left; 4: Back-Right
126                         5 => '4-channel', // 1: Front-Left; 2: Front-Right; 3: Center;    4: Low-Frequency
127                         6 => '5-channel', // 1: Front-Left; 2: Front-Right; 3: Center;    4: Back-Left      5: Back-Right
128                         7 => '5.1',       // 1: Front-Left; 2: Front-Right; 3: Center;    4: Low-Frequency; 5: Back-Left;  6: Back-Right
129                 );
130                 return (isset($DSFchannelTypeLookup[$channel_type_id]) ? $DSFchannelTypeLookup[$channel_type_id] : '');
131         }
132
133 }