ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
module.audio.dsf.php
Go to the documentation of this file.
1 <?php
4 // available at http://getid3.sourceforge.net //
5 // or http://www.getid3.org //
6 // also https://github.com/JamesHeinrich/getID3 //
8 // See readme.txt for more details //
10 // //
11 // module.audio.dsf.php //
12 // module for analyzing dsf/DSF Audio files //
13 // dependencies: module.tag.id3v2.php //
14 // ///
16 
17 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
18 
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 }
error($text)
Definition: getid3.php:1752
static LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:292
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
Definition: getid3.lib.php:18
fread($bytes)
Definition: getid3.php:1683
Create styles array
The data for the language used.
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1711
$info
Definition: index.php:5
static DSFchannelTypeLookup($channel_type_id)