source: extensions/charlies_content/getid3/getid3/module.audio.vqf.php @ 3318

Revision 3318, 6.7 KB checked in by vdigital, 10 years ago (diff)

+ Add Charlies' content to depository

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2// +----------------------------------------------------------------------+
3// | PHP version 5                                                        |
4// +----------------------------------------------------------------------+
5// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 |
6// +----------------------------------------------------------------------+
7// | This source file is subject to version 2 of the GPL license,         |
8// | that is bundled with this package in the file license.txt and is     |
9// | available through the world-wide-web at the following url:           |
10// | http://www.gnu.org/copyleft/gpl.html                                 |
11// +----------------------------------------------------------------------+
12// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    |
13// +----------------------------------------------------------------------+
14// | Authors: James Heinrich <infoØgetid3*org>                            |
15// |          Allan Hansen <ahØartemis*dk>                                |
16// +----------------------------------------------------------------------+
17// | module.audio.vqf.php                                                 |
18// | Module for analyzing VQF Audio files                                 |
19// | dependencies: NONE                                                   |
20// +----------------------------------------------------------------------+
21//
22// $Id$
23
24       
25       
26class getid3_vqf extends getid3_handler
27{
28
29    public function Analyze() {
30       
31        $getid3 = $this->getid3;   
32
33        // based loosely on code from TTwinVQ by Jurgen Faul <jfaulØgmx*de>
34        // http://jfaul.de/atl  or  http://j-faul.virtualave.net/atl/atl.html
35
36        $getid3->info['fileformat']            = 'vqf';
37        $getid3->info['audio']['dataformat']   = 'vqf';
38        $getid3->info['audio']['bitrate_mode'] = 'cbr';
39        $getid3->info['audio']['lossless']     = false;
40
41        // Shortcuts
42        $getid3->info['vqf']['raw'] = array ();
43        $info_vqf      = &$getid3->info['vqf'];
44        $info_vqf_raw  = &$info_vqf['raw'];
45
46        // Get header
47        fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
48        $vqf_header_data = fread($getid3->fp, 16);
49
50        $info_vqf_raw['header_tag'] = 'TWIN';   // Magic bytes
51        $info_vqf_raw['version']    = substr($vqf_header_data, 4, 8);
52        $info_vqf_raw['size']       = getid3_lib::BigEndian2Int(substr($vqf_header_data, 12, 4));
53       
54        while (ftell($getid3->fp) < $getid3->info['avdataend']) {
55
56            $chunk_base_offset = ftell($getid3->fp);
57            $chunk_data        = fread($getid3->fp, 8);
58            $chunk_name        = substr($chunk_data, 0, 4);
59           
60            if ($chunk_name == 'DATA') {
61                $getid3->info['avdataoffset'] = $chunk_base_offset;
62                break;
63            }
64           
65            $chunk_size = getid3_lib::BigEndian2Int(substr($chunk_data, 4, 4));
66            if ($chunk_size > ($getid3->info['avdataend'] - ftell($getid3->fp))) {
67                throw new getid3_exception('Invalid chunk size ('.$chunk_size.') for chunk "'.$chunk_name.'" at offset 8.');
68            }
69            if ($chunk_size > 0) {
70                $chunk_data .= fread($getid3->fp, $chunk_size);
71            }
72
73            switch ($chunk_name) {
74               
75                case 'COMM':
76                    $info_vqf['COMM'] = array ();
77                    getid3_lib::ReadSequence('BigEndian2Int', $info_vqf['COMM'], $chunk_data, 8, 
78                        array (
79                            'channel_mode'   => 4,
80                            'bitrate'        => 4,
81                            'sample_rate'    => 4,
82                            'security_level' => 4
83                        )
84                    );
85
86                    $getid3->info['audio']['channels']        = $info_vqf['COMM']['channel_mode'] + 1;
87                    $getid3->info['audio']['sample_rate']     = getid3_vqf::VQFchannelFrequencyLookup($info_vqf['COMM']['sample_rate']);
88                    $getid3->info['audio']['bitrate']         = $info_vqf['COMM']['bitrate'] * 1000;
89                    $getid3->info['audio']['encoder_options'] = 'CBR' . ceil($getid3->info['audio']['bitrate']/1000);
90
91                    if ($getid3->info['audio']['bitrate'] == 0) {
92                        throw new getid3_exception('Corrupt VQF file: bitrate_audio == zero');
93                    }
94                    break;
95
96                case 'NAME':
97                case 'AUTH':
98                case '(c) ':
99                case 'FILE':
100                case 'COMT':
101                case 'ALBM':
102                    $info_vqf['comments'][getid3_vqf::VQFcommentNiceNameLookup($chunk_name)][] = trim(substr($chunk_data, 8));
103                    break;
104
105                case 'DSIZ':
106                    $info_vqf['DSIZ'] = getid3_lib::BigEndian2Int(substr($chunk_data, 8, 4));
107                    break;
108
109                default:
110                    $getid3->warning('Unhandled chunk type "'.$chunk_name.'" at offset 8');
111                    break;
112            }
113        }
114
115        $getid3->info['playtime_seconds'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['audio']['bitrate'];
116
117        if (isset($info_vqf['DSIZ']) && (($info_vqf['DSIZ'] != ($getid3->info['avdataend'] - $getid3->info['avdataoffset'] - strlen('DATA'))))) {
118            switch ($info_vqf['DSIZ']) {
119                case 0:
120                case 1:
121                    $getid3->warning('Invalid DSIZ value "'.$info_vqf['DSIZ'].'". This is known to happen with VQF files encoded by Ahead Nero, and seems to be its way of saying this is TwinVQF v'.($info_vqf['DSIZ'] + 1).'.0');
122                    $getid3->info['audio']['encoder'] = 'Ahead Nero';
123                    break;
124
125                default:
126                    $getid3->warning('Probable corrupted file - should be '.$info_vqf['DSIZ'].' bytes, actually '.($getid3->info['avdataend'] - $getid3->info['avdataoffset'] - strlen('DATA')));
127                    break;
128            }
129        }
130
131        return true;
132    }
133   
134
135
136    public static function VQFchannelFrequencyLookup($frequencyid) {
137       
138        static $lookup = array (
139            11 => 11025,
140            22 => 22050,
141            44 => 44100
142        );
143        return (isset($lookup[$frequencyid]) ? $lookup[$frequencyid] : $frequencyid * 1000);
144    }
145
146
147
148    public static function VQFcommentNiceNameLookup($shortname) {
149       
150        static $lookup = array (
151            'NAME' => 'title',
152            'AUTH' => 'artist',
153            '(c) ' => 'copyright',
154            'FILE' => 'filename',
155            'COMT' => 'comment',
156            'ALBM' => 'album'
157        );
158        return (isset($lookup[$shortname]) ? $lookup[$shortname] : $shortname);
159    }
160
161}
162
163
164?>
Note: See TracBrowser for help on using the repository browser.