-
Notifications
You must be signed in to change notification settings - Fork 1
/
cr-test-harness.js
179 lines (152 loc) · 5.8 KB
/
cr-test-harness.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
var fs = require('fs');
var crypto = require('crypto');
var SAMPLE_RATE = 44100;
var WAV_HEADER_SIZE = 44;
if (process.argv.length < 4)
{
console.log("USAGE: nodejs cr-test-harness.js <test-spec.json> <output.wav>");
process.exit(1);
}
var testSpecFilename = process.argv[2];
var outputFile = process.argv[3];
testSpec = JSON.parse(fs.readFileSync(testSpecFilename).toString());
/* make sure that the voice count matches the voice name array */
if (testSpec['expected-voice-names'].length != testSpec['expected-voice-count'])
{
console.log("test spec claims " + testSpec['expected-voice-count'] +
" voices but only names " + testSpec['expected-voice-names'].length +
" voices");
}
var player = require(testSpec['player']);
var musicBuffer;
var seconds;
var currentChannelDisabled = -1;
if (!fs.existsSync(testSpec['filename']))
{
console.log(testSpec['filename'] + " does not exist");
process.exit(1);
}
musicBuffer = fs.readFileSync(testSpec['filename']);
/* create memory for the context */
var contextSize = player._crPlayerContextSize();
var contextMalloc = player._malloc(contextSize);
var context = new Uint8Array(player.HEAPU8.buffer, contextMalloc, contextSize);
/* initialize the player */
ret = player._crPlayerInitialize(context.byteOffset, SAMPLE_RATE);
if (ret != 1)
{
console.log("crPlayerInitialize() returned " + ret);
process.exit(1);
}
/* create memory for the music */
var musicBufferBytes = new Uint8Array(musicBuffer);
var bytesMalloc = player._malloc(musicBufferBytes.length);
var bytes = new Uint8Array(player.HEAPU8.buffer, bytesMalloc, musicBufferBytes.length);
bytes.set(new Uint8Array(musicBufferBytes.buffer));
/* load the file */
ret = player._crPlayerLoadFile(context.byteOffset, 0, bytes.byteOffset,
bytes.length);
if (ret != 1)
{
console.log("crPlayerLoadFile() returned " + ret);
process.exit(1);
}
/* start the track */
ret = player._crPlayerSetTrack(context.byteOffset, testSpec['track']);
if (ret != testSpec['expected-output-channels'])
{
console.log("crPlayerSetTrack() returned " + ret + " (expected " + testSpec['expected-output-channels'] + ")");
process.exit(1);
}
/* how many voices? that count + 1 is the number of seconds to run */
var voiceCount = player._crPlayerGetVoiceCount(context.byteOffset);
if (voiceCount != testSpec['expected-voice-count'])
{
console.log("crPlayerGetVoiceCount() returned " + voiceCount + " (expected " + testSpec['expected-voice-count'] + ")");
process.exit(1);
}
/* do the voice names match up? */
var voiceName;
var expectedNames = testSpec['expected-voice-names'];
for (var i = 0; i < voiceCount; i++)
{
voiceName = player.Pointer_stringify(player._crPlayerGetVoiceName(context.byteOffset, i));
expectedName = expectedNames.shift();
if (voiceName != expectedName)
console.log("voice " + i + ": expected '" + expectedName + "'; got '" + voiceName + "'");
}
seconds = voiceCount + 1;
/* create an array for the player to use for sample generation */
var samplesCount = SAMPLE_RATE * 2; /* 2 channels / frame */
var samplesCountInBytes = samplesCount * 2; /* 2 bytes/sample */
var samplesMalloc = player._malloc(samplesCountInBytes);
var samples = new Int16Array(player.HEAP16.buffer, samplesMalloc, samplesCount);
/* create the WAV header and write to disk */
byteCount = SAMPLE_RATE * 2 * 2 * seconds;
var header = new Buffer(WAV_HEADER_SIZE);
header.writeUInt8(0x52, 0); /* R */
header.writeUInt8(0x49, 1); /* I */
header.writeUInt8(0x46, 2); /* F */
header.writeUInt8(0x46, 3); /* F */
header.writeUInt32LE(byteCount + WAV_HEADER_SIZE - 8, 4); /* header size */
header.writeUInt8(0x57, 8); /* W */
header.writeUInt8(0x41, 9); /* A */
header.writeUInt8(0x56, 10); /* V */
header.writeUInt8(0x45, 11); /* E */
header.writeUInt8(0x66, 12); /* f */
header.writeUInt8(0x6D, 13); /* m */
header.writeUInt8(0x74, 14); /* t */
header.writeUInt8(0x20, 15); /* */
header.writeUInt32LE(0x10, 16); /* size of 'fmt ' header */
header.writeUInt16LE(0x01, 20); /* integer PCM */
header.writeUInt16LE(0x02, 22); /* channels */
header.writeUInt32LE(SAMPLE_RATE, 24); /* sample rate */
header.writeUInt32LE(SAMPLE_RATE * 2 * 2, 28); /* bytes/second */
header.writeUInt16LE(4, 32); /* block alignment */
header.writeUInt16LE(16, 34); /* bits/sample */
header.writeUInt8(0x64, 36); /* d */
header.writeUInt8(0x61, 37); /* a */
header.writeUInt8(0x74, 38); /* t */
header.writeUInt8(0x61, 39); /* a */
header.writeUInt32LE(byteCount, 40); /* byte count */
var outBufferSize = SAMPLE_RATE * 2 * 2;
var outBuffer = new Buffer(outBufferSize);
var wavFd = fs.openSync(outputFile, "w");
ret = fs.writeSync(wavFd, header, 0, WAV_HEADER_SIZE);
while (seconds > 0)
{
ret = player._crPlayerGenerateStereoFrames(context.byteOffset, samples.byteOffset, SAMPLE_RATE);
if (ret != 1)
{
console.log("crPlayerGenerateStereoFrames() returned " + ret);
process.exit(1);
}
for (j = 0; j < samplesCount; j++)
{
outBuffer.writeInt16LE(samples[j], j * 2);
}
fs.writeSync(wavFd, outBuffer, 0, outBufferSize);
/* deal with channel toggles */
if (currentChannelDisabled >= 0)
{
player._crPlayerSetVoiceState(context.byteOffset, currentChannelDisabled, 1);
}
currentChannelDisabled += 1;
player._crPlayerSetVoiceState(context.byteOffset, currentChannelDisabled, 0);
seconds -= 1;
}
ret = fs.closeSync(wavFd);
/* checksum the file */
var md5sum = crypto.createHash("md5");
var output = fs.readFileSync(outputFile);
md5sum.update(output);
var digest = md5sum.digest('hex');
if (digest != testSpec['expected-md5'])
{
console.log("md5 hash of output differs");
console.log(" expected: " + testSpec['expected-md5']);
console.log(" got: " + digest);
process.exit(1);
}
/* cleanly shutdown the player */
player._crPlayerCleanup(context.byteOffset);