Skip to content

Commit

Permalink
md: better handle 32X PWM sample/clock rate changes
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeUsher committed Jan 31, 2025
1 parent 6cc9f5a commit 9c273ab
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 23 deletions.
1 change: 1 addition & 0 deletions ares/md/m32x/m32x.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ struct M32X {
auto main() -> void;
auto step(u32 clocks) -> void;
auto power(bool reset) -> void;
auto updateFrequency() -> void;

//serialization.cpp
auto serialize(serializer&) -> void;
Expand Down
58 changes: 35 additions & 23 deletions ares/md/m32x/pwm.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
auto M32X::PWM::load(Node::Object parent) -> void {
stream = parent->append<Node::Audio::Stream>("PWM");
stream->setChannels(2);
stream->setFrequency(44'100);
n12 clocks = cycle - 1;
updateFrequency();
}

auto M32X::PWM::unload(Node::Object parent) -> void {
Expand All @@ -10,36 +11,41 @@ auto M32X::PWM::unload(Node::Object parent) -> void {
}

auto M32X::PWM::main() -> void {
n12 clocks = cycle-1;
if(clocks && (lmode.bit(0)^lmode.bit(1) || rmode.bit(0)^rmode.bit(1))) {
if(lmode == 1) lsample = lfifo.read();
if(lmode == 2) lsample = rfifo.read();
n12 clocks = cycle - 1;

if(rmode == 1) rsample = rfifo.read();
if(rmode == 2) rsample = lfifo.read();
//check if cycle rate has changed and update sample rate accordingly
static n12 previousCycle = cycle;
if (cycle != previousCycle) {
previousCycle = cycle;
updateFrequency();
}

if (clocks && (lmode.bit(0) ^ lmode.bit(1) || rmode.bit(0) ^ rmode.bit(1))) {
if (lmode == 1) lsample = lfifo.read();
if (lmode == 2) lsample = rfifo.read();

if (rmode == 1) rsample = rfifo.read();
if (rmode == 2) rsample = lfifo.read();

lfifoLatch.bit(14) = lfifo.empty();
rfifoLatch.bit(14) = rfifo.empty();
mfifoLatch.bit(14) = lfifoLatch.bit(14) & rfifoLatch.bit(14);
lfifoLatch.bit(14) = lfifo.empty();
rfifoLatch.bit(14) = rfifo.empty();
mfifoLatch.bit(14) = lfifoLatch.bit(14) & rfifoLatch.bit(14);

if(periods++ == n4(timer-1)) {
periods = 0;
m32x.shm.irq.pwm.active = 1;
m32x.shs.irq.pwm.active = 1;
m32x.shm.dmac.dreq[1] = dreqIRQ;
m32x.shs.dmac.dreq[1] = dreqIRQ;
if (periods++ == n4(timer - 1)) {
periods = 0;
m32x.shm.irq.pwm.active = 1;
m32x.shs.irq.pwm.active = 1;
m32x.shm.dmac.dreq[1] = dreqIRQ;
m32x.shs.dmac.dreq[1] = dreqIRQ;
}
}
}

counter += max(1, clocks);
while(counter >= 522) {
counter -= 522;
auto left = cycle > 0 ? lsample / (f32)cycle : 0;
auto right = cycle > 0 ? rsample / (f32)cycle : 0;
stream->frame(left, right);
}

step(clocks);
stream->frame(left, right); // Output the frame without the loop, since the sample rate is adjusted dynamically

step(clocks);
}

auto M32X::PWM::step(u32 clocks) -> void {
Expand All @@ -64,4 +70,10 @@ auto M32X::PWM::power(bool reset) -> void {
lfifoLatch = 0x4000; // empty
rfifoLatch = 0x4000; // empty
mfifoLatch = 0x4000; // empty
updateFrequency();
}

auto M32X::PWM::updateFrequency() -> void {
n12 clocks = cycle - 1;
stream->setFrequency((system.frequency() * 6) / (7.0 * (2 * (clocks) - 1)));
}

0 comments on commit 9c273ab

Please sign in to comment.