Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: whitequark/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 34d6c358e406
Choose a base ref
...
head repository: whitequark/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f35ce43cfbbb
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Feb 18, 2019

  1. Copy the full SHA
    a79439c View commit details
  2. Copy the full SHA
    f35ce43 View commit details
Showing with 48 additions and 20 deletions.
  1. +48 −20 software/glasgow/applet/audio_output/__init__.py
68 changes: 48 additions & 20 deletions software/glasgow/applet/audio_output/__init__.py
Original file line number Diff line number Diff line change
@@ -7,41 +7,65 @@


class AudioOutputSubtarget(Module):
def __init__(self, pads, out_fifo, sample_cyc):
count = Signal(8)
limit = Signal(8)

self.sync += count.eq(count + 1)
self.comb += pads.o_t.o.eq(count < limit)
def __init__(self, pads, out_fifo, sample_cyc, width):
assert width in (1, 2)

timer = Signal(max=sample_cyc)
self.sync += [
out_fifo.re.eq(0),
accum = Signal(width * 8)
level = Signal(width * 8)

self.sync += Cat(accum, pads.o_t.o).eq(accum + level)

self.submodules.fsm = FSM()
self.fsm.act("STANDBY",
NextValue(pads.o_t.oe, 0),
If(out_fifo.readable,
NextValue(pads.o_t.oe, 1),
NextState("WAIT")
)
)
self.fsm.act("WAIT",
If(timer == 0,
timer.eq(sample_cyc - 1),
NextValue(timer, sample_cyc - width - 1),
NextState("READ-1")
).Else(
NextValue(timer, timer - 1)
)
)
self.fsm.act("READ-1",
out_fifo.re.eq(1),
If(out_fifo.readable,
NextValue(level[0:8], out_fifo.dout),
NextState("WAIT" if width == 1 else "READ-2")
).Else(
NextState("STANDBY")
)
)
if width > 1:
self.fsm.act("READ-2",
out_fifo.re.eq(1),
If(out_fifo.readable,
out_fifo.re.eq(1),
pads.o_t.oe.eq(1),
limit.eq(out_fifo.dout)
NextValue(level[8:16], out_fifo.dout),
NextState("WAIT")
).Else(
pads.o_t.oe.eq(0),
NextState("STANDBY")
)
).Else(
timer.eq(timer - 1)
)
]


class AudioOutputApplet(GlasgowApplet, name="audio-output"):
logger = logging.getLogger(__name__)
help = "play sound using pulse width modulation"
help = "play sound using a ΣΔ-DAC"
description = """
Play sound using pulse width modulation.
Play sound using a 1-bit sigma-delta DAC, i.e. pulse density modulation.
Currently, the supported sample formats are:
* mono unsigned 8-bit,
* mono unsigned 16-bit little endian.
Currently, only one sample format is supported: mono unsigned 8-bit.
Other formats may be converted to it using:
sox <input> -c 1 -r <rate> <output>.u8
sox <input> -c 1 -r <rate> <output>.<u8|u16>
"""

__pins = ("o",)
@@ -55,13 +79,17 @@ def add_build_arguments(cls, parser, access):
parser.add_argument(
"-r", "--sample-rate", metavar="FREQ", type=int, default=8000,
help="set sample rate to FREQ Hz (default: %(default)d)")
parser.add_argument(
"-w", "--width", metavar="WIDTH", type=int, default=1,
help="set sample width to WIDTH bytes (default: %(default)d)")

def build(self, target, args):
self.mux_interface = iface = target.multiplexer.claim_interface(self, args)
subtarget = iface.add_subtarget(AudioOutputSubtarget(
pads=iface.get_pads(args, pins=self.__pins),
out_fifo=iface.get_out_fifo(),
sample_cyc=int(target.sys_clk_freq // args.sample_rate),
width=args.width,
))
return subtarget