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: 13815e575fb9
Choose a base ref
...
head repository: whitequark/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6c47f86354e3
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Feb 11, 2019

  1. Copy the full SHA
    6c47f86 View commit details
Showing with 86 additions and 0 deletions.
  1. +1 −0 software/glasgow/applet/__init__.py
  2. +85 −0 software/glasgow/applet/audio_output/__init__.py
1 change: 1 addition & 0 deletions software/glasgow/applet/__init__.py
Original file line number Diff line number Diff line change
@@ -338,6 +338,7 @@ def run_test():

# -------------------------------------------------------------------------------------------------

from .audio_output import AudioOutputApplet
from .benchmark import BenchmarkApplet
from .rgb_grabber import RGBGrabberApplet
from .hd44780 import HD44780Applet
85 changes: 85 additions & 0 deletions software/glasgow/applet/audio_output/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import logging
import argparse
from migen import *

from .. import *
from ...gateware.pads import *


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)

timer = Signal(max=sample_cyc)
self.sync += [
out_fifo.re.eq(0),
If(timer == 0,
timer.eq(sample_cyc - 1),
If(out_fifo.readable,
out_fifo.re.eq(1),
pads.o_t.oe.eq(1),
limit.eq(out_fifo.dout)
).Else(
pads.o_t.oe.eq(0),
)
).Else(
timer.eq(timer - 1)
)
]


class AudioOutputApplet(GlasgowApplet, name="audio-output"):
logger = logging.getLogger(__name__)
help = "play sound using pulse width modulation"
description = """
Play sound using pulse width modulation.
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
"""

__pins = ("o",)

@classmethod
def add_build_arguments(cls, parser, access):
super().add_build_arguments(parser, access)

access.add_pin_argument(parser, "o", default=True)

parser.add_argument(
"-r", "--sample-rate", metavar="FREQ", type=int, default=8000,
help="set sample rate to FREQ Hz (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),
))
return subtarget

async def run(self, device, args):
return await device.demultiplexer.claim_interface(self, self.mux_interface, args)

@classmethod
def add_interact_arguments(cls, parser):
parser.add_argument(
"file", metavar="FILE", type=argparse.FileType("rb"),
help="read PCM data from FILE")

async def interact(self, device, args, pcm_iface):
await pcm_iface.write(args.file.read())

# -------------------------------------------------------------------------------------------------

class AudioOutputAppletTestCase(GlasgowAppletTestCase, applet=AudioOutputApplet):
@synthesis_test
def test_build(self):
self.assertBuilds()