Skip to content

Commit

Permalink
Merge pull request #711 from JerwuQu/jwq_apu-triangle-fix
Browse files Browse the repository at this point in the history
apu: fix continous tone for triangle
  • Loading branch information
aduros authored Apr 20, 2024
2 parents 60f3947 + 74694d7 commit cb6250e
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
8 changes: 5 additions & 3 deletions runtimes/native/src/apu.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

#define SAMPLE_RATE 44100
#define MAX_VOLUME 0x1333 // ~15% of INT16_MAX
// The triangle channel sounds a bit quieter than the others, so give it higher amplitude
#define MAX_VOLUME_TRIANGLE 0x2000 // ~25% of INT16_MAX
// Also the triangle channel prevent popping on hard stops by adding a 1 ms release
#define RELEASE_TIME_TRIANGLE (SAMPLE_RATE / 1000)

typedef struct {
/** Starting frequency. */
Expand Down Expand Up @@ -97,7 +100,7 @@ static float getCurrentFrequency (const Channel* channel) {
}

static int16_t getCurrentVolume (const Channel* channel) {
if (time >= channel->sustainTime && channel->releaseTime != channel->sustainTime) {
if (time >= channel->sustainTime && (channel->releaseTime - channel->sustainTime) > RELEASE_TIME_TRIANGLE) {
// Release
return ramp(channel->sustainVolume, 0, channel->sustainTime, channel->releaseTime);
} else if (time >= channel->decayTime) {
Expand Down Expand Up @@ -192,9 +195,8 @@ void w4_apuTone (int frequency, int duration, int volume, int flags) {
}

} else if (channelIdx == 2) {
// For the triangle channel, prevent popping on hard stops by adding a 1 ms release
if (release == 0) {
channel->releaseTime += SAMPLE_RATE/1000;
channel->releaseTime += RELEASE_TIME_TRIANGLE;
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions runtimes/web/src/apu-worklet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
// Audio worklet file: do not export anything directly.
const SAMPLE_RATE = 44100;
const MAX_VOLUME = 0.15;
// The triangle channel sounds a bit quieter than the others, so give it higher amplitude
const MAX_VOLUME_TRIANGLE = 0.25;
// Also the triangle channel prevent popping on hard stops by adding a 1 ms release
const RELEASE_TIME_TRIANGLE = Math.floor(SAMPLE_RATE / 1000);

class Channel {
/** Starting frequency. */
Expand Down Expand Up @@ -114,7 +117,7 @@ class APUProcessor extends AudioWorkletProcessor {

getCurrentVolume (channel: Channel) {
const time = this.time;
if (time >= channel.sustainTime && channel.releaseTime != channel.sustainTime) {
if (time >= channel.sustainTime && (channel.releaseTime - channel.sustainTime) > RELEASE_TIME_TRIANGLE) {
// Release
return this.ramp(channel.sustainVolume, 0, channel.sustainTime, channel.releaseTime);
} else if (time >= channel.decayTime) {
Expand Down Expand Up @@ -188,9 +191,8 @@ class APUProcessor extends AudioWorkletProcessor {
}

} else if (channelIdx == 2) {
// For the triangle channel, prevent popping on hard stops by adding a 1 ms release
if (release == 0) {
channel.releaseTime += (SAMPLE_RATE/1000) >>> 0;
channel.releaseTime += RELEASE_TIME_TRIANGLE;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion runtimes/web/src/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,8 @@ export class Runtime {
let update_function = this.wasm!.exports["update"];
if (typeof update_function === "function") {
this.bluescreenOnError(update_function);
this.apu.tick();
}
this.apu.tick();
}

blueScreen (text: string) {
Expand Down

0 comments on commit cb6250e

Please sign in to comment.