Skip to content

Commit

Permalink
fix stepbufferwriter
Browse files Browse the repository at this point in the history
  • Loading branch information
shicks committed Jan 10, 2016
1 parent a9a489b commit f5677b8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 26 deletions.
4 changes: 4 additions & 0 deletions apu/apu.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ export default class Apu {
const tndOut = (triangle || noise || dmc) &&
159.79 / (1 / (triangle / 8227 + noise / 12241 + dmc / 22638) + 100);

//console.log('volume=' + (pulseOut + tndOut));
return pulseOut + tndOut;

// TODO(sdh): consider using the linear approximation and adjusting
// all the APU units to output waves centered at zero.
}
}

Expand Down
45 changes: 20 additions & 25 deletions audio/stepbufferwriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,62 +16,57 @@ export default class StepBufferWriter {

/** @private {number} Current sample index. */
this.sampleIndex_ = 0;
/** @private {number} Last sample value. */
/** @private {number} Last sample value read from steps. */
this.lastStep_ = 0;
/** @private {number} Last sample value written to buffer. */
this.lastSample_ = 0;
/** @private {!Array<!Array<number>>} Steps we currently care about. */
this.steps_ = [];

// this.kernel_ = new StepKernel([[.5, .5], [.5, .5]]);
// this.kernel_ = new StepKernel([[1, 0], [0, 1]]);
this.kernel_ = new StepKernel([[1, 0], [0, 1]]);

/** @private @const {!StepKernel} */
this.kernel_ = lanczosKernel(5, 32);
//this.kernel_ = lanczosKernel(5, 32);
}


/**
* @param {!Array<!Array<number>>} steps Array of [time (s), sample]
* indicating transition times between steps.
* @param {number} time "Current" ending time.
* @return {!Promise}
*/
write(steps, time) {
console.log('WRITE: [' + steps + '], ' + time);
write(steps) {

// TODO(sdh): consider having the input always start at zero?

//console.log('WRITE: [' + steps.map(s=>`[${s[0]},${s[1]}]`) + ']');
if (!steps.length) return new Promise(resolve => setTimeout(resolve, 50));

const samples = [];
const endTime = time - 2 * this.kernel_.radius * this.sampleRate_;
// Add a final (zero) step.
if (steps.length == 0 || steps[steps.length - 1][0] < endTime) {

// TODO - why aren't we outputting anything for empty steps?!?
// ....?!?
// -- consider separating steps from time, and having
// time just output regardless? but how to know when ready?

steps = steps.slice();
steps.push([
endTime,
steps.length ? steps[steps.length - 1][1] : this.lastSample_]);
}

for (let step of steps) {
// console.log('step: ' + step[0] + ', ' + step[1]);
const s = step[0] * this.sampleRate_;
const v = step[1] - this.lastSample_;
const v = step[1] - this.lastStep_;
this.lastStep_ = step[1];
//console.log('step: [' + s + ', ' + v + ']');

// console.log(`step: ${step} s=${s} v=${v} sampleIndex=${this.sampleIndex_} endSample=${Math.floor(s - this.kernel_.radius)}`);

if (s <= this.sampleIndex_) {
this.lastSample_ = step[1];
this.lastStep_ = this.lastSample_ = step[1];
this.steps_ = [];
console.log('past value: resetting');
continue;
}
this.lastSample_ += v;
//this.lastSample_ += v;

// Compute samples until s - kernel.radius
const endSample = Math.floor(s - this.kernel_.radius);
if (endSample > this.sampleIndex_) {
const deltas =
this.kernel_.convolve(this.sampleIndex_, endSample, this.steps_)
this.kernel_.convolve(this.sampleIndex_, endSample, this.steps_)
for (let delta of /** @type {!Iterable<number>} */ (deltas)) {
// TODO(sdh): can we remove the floating-point error drift?!?
//this.lastSample_ *= 0.9999995;
Expand All @@ -88,7 +83,7 @@ export default class StepBufferWriter {
this.steps_.push([s, v]);
}
// now write the buffer.
console.log(`Writing ${samples.length} samples`);
//console.log(`Writing ${samples.length} samples`, samples);
return this.buffer_.write(samples);
}
}
Expand Down
2 changes: 1 addition & 1 deletion nsfplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default class NsfPlayer {
// Yield a single frame worth of steps
promise = this.promise =
this.writer.write(this.apu.steps(), this.clock.time)
.then(() => this.play(promise));
.then(() => { setTimeout(() => this.play(promise), 1); });
// console.log('Yield data', data);
}

Expand Down

0 comments on commit f5677b8

Please sign in to comment.