-
Notifications
You must be signed in to change notification settings - Fork 1
/
aiff-file-info.js
128 lines (90 loc) · 3.54 KB
/
aiff-file-info.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//Hi, AFI by David Jones / RackFX, LLC
var buffertools = require('buffertools');
var fs = require('fs');
var afi = {};
afi.infoByFilename = function(filename, cb){
var stats = fs.statSync(filename);
var buffer = new Buffer(160);
fs.open(filename, 'r', function(err, fd){
if (err) return cb(err);
var read_result = {}
var reads = [
['form_identifier', 'string', 4],
['chunk_size', 'uinteger', 4],
['aiff_identifier', 'string',4],
['comm_identifier', 'string', 4],
['chunk_length', 'uinteger', 4],
['num_channels', 'uinteger',2],
['num_sample_frames', 'uinteger', 4],
['bits_per_sample','uinteger',2],
['sample_rate1','uinteger',2],
['sample_rate2','uinteger',1],
['sample_rate3','uinteger',1],
]
fs.read(fd,buffer,0,80,0,function(err,num){
var i=0;
var pointer = 0;
function read_aif(){
var read = reads[i];
i++;
if(i == 5){
// the following handles AIFC file format... Nice.
if((read_result.aiff_identifier == "AIFC") && (read_result.comm_identifier == "FVER")){
reads.splice(5, 0, ['junk_length', 'long', 12]);
}
}
if(read[1]=='string'){
read_result[read[0]] = buffer.toString('ascii', pointer , pointer + read[2]);
pointer = pointer + read[2]; // pointer = pointer plus # bytes
}
else if(read[1]=='integer'){
read_result[read[0]] = buffer.readUIntLE(pointer, read[2])
pointer = pointer + read[2];
}
else if(read[1]=='uinteger'){
read_result[read[0]] = buffer.readUIntBE(pointer, read[2])
pointer = pointer + read[2];
}
else if(read[1]=='extendfloat'){
read_result[read[0]] = buffer.toString('ascii', pointer , pointer + read[2]);
pointer = pointer + read[2];
}
else if(read[1]=="long"){
read_result[read[0]] = buffer.readInt32LE(pointer, read[2])
pointer = pointer + read[2];
}
if(i < reads.length) { return read_aif()}
else { return post_process(); }
}
read_aif();
function post_process(){
var pad = read_result.sample_rate1 - 16398;
var shifted = (read_result.sample_rate2<<8) + read_result.sample_rate3 ;
read_result.sample_rate = shifted << pad;
// read_result.pad = pad;
// read_result.shifted = shifted;
delete read_result.sample_rate1;
delete read_result.sample_rate2;
delete read_result.sample_rate3;
var error = false;
var invalid_reasons = []
if(read_result.form_identifier != "FORM") invalid_reasons.push("Expected \"FORM\" string at 0")
if((read_result.aiff_identifier != "AIFF") && (read_result.aiff_identifier != "AIFC")) invalid_reasons.push("Expected \"AIFF\" or \"AIFC\" string")
if((read_result.comm_identifier != "COMM") && (read_result.comm_identifier != "FVER")) invalid_reasons.push("Expected \"COMM\" or \"FVER\" string")
if (invalid_reasons.length > 0) error = true;
if (error) return cb({
error : true,
invalid_reasons: invalid_reasons,
header: read_result,
stats: stats
});
cb(null, {
header: read_result,
stats: stats,
duration: ((read_result.chunk_size) / (read_result.sample_rate * read_result.num_channels * (read_result.bits_per_sample / 8)))
});
}
})
})
}
module.exports = afi;