From f54ffe555c7be3cc674833953fd5d8aba1a88e17 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Sun, 13 Oct 2013 17:30:32 +0200 Subject: Add new i2s_dump protocol decoder. This stacks of top of the 'i2s' decoder and outputs the audio data to file (or stdout) in various formats. Currently only WAV is supported. This is work in progress, it has various hard-coded assumptions. --- decoders/Makefile.am | 1 + decoders/i2s_dump/Makefile.am | 26 ++++++++++ decoders/i2s_dump/__init__.py | 26 ++++++++++ decoders/i2s_dump/pd.py | 107 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 decoders/i2s_dump/Makefile.am create mode 100644 decoders/i2s_dump/__init__.py create mode 100644 decoders/i2s_dump/pd.py (limited to 'decoders') diff --git a/decoders/Makefile.am b/decoders/Makefile.am index 34843f2..4ad5930 100644 --- a/decoders/Makefile.am +++ b/decoders/Makefile.am @@ -29,6 +29,7 @@ SUBDIRS = \ i2cdemux \ i2cfilter \ i2s \ + i2s_dump \ jtag \ jtag_stm32 \ lm75 \ diff --git a/decoders/i2s_dump/Makefile.am b/decoders/i2s_dump/Makefile.am new file mode 100644 index 0000000..fda1fff --- /dev/null +++ b/decoders/i2s_dump/Makefile.am @@ -0,0 +1,26 @@ +## +## This file is part of the libsigrokdecode project. +## +## Copyright (C) 2013 Uwe Hermann +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +pkgdatadir = $(DECODERS_DIR)/i2s_dump + +dist_pkgdata_DATA = __init__.py pd.py + +CLEANFILES = *.pyc + diff --git a/decoders/i2s_dump/__init__.py b/decoders/i2s_dump/__init__.py new file mode 100644 index 0000000..6b24953 --- /dev/null +++ b/decoders/i2s_dump/__init__.py @@ -0,0 +1,26 @@ +## +## This file is part of the libsigrokdecode project. +## +## Copyright (C) 2013 Uwe Hermann +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +''' +TODO. +''' + +from .pd import * + diff --git a/decoders/i2s_dump/pd.py b/decoders/i2s_dump/pd.py new file mode 100644 index 0000000..8f95a86 --- /dev/null +++ b/decoders/i2s_dump/pd.py @@ -0,0 +1,107 @@ +## +## This file is part of the libsigrokdecode project. +## +## Copyright (C) 2013 Uwe Hermann +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +import sigrokdecode as srd +import os +import sys + +class Decoder(srd.Decoder): + api_version = 1 + id = 'i2s_dump' + name = 'I2S dump' + longname = 'I2S dump' + desc = 'Output decoded I2S data to a file.' + license = 'gplv2+' + inputs = ['i2s'] + outputs = [] + probes = [] + optional_probes = [] + options = { + 'format': ['File format for the output data', 'wav'], + 'filename': ['File name for the output data', '-'], + } + annotations = [] + + def __init__(self, **kwargs): + self.wrote_header = False + self.f = None + + def file_open(self, filename): + if filename == 'none': + return None + elif filename == '-': + return sys.stdout + else: + return open(filename, 'wb') + + def start(self, metadata): + # A filename of 'none' is not allowed (has special meaning). A filename + # of '-' means 'stdout'. + self.f = self.file_open(self.options['filename']) + + def report(self): + pass + + # TODO: Lots of hard-coded fields in here. + def write_wav_header(self): + # Chunk descriptor + self.f.write(b'RIFF') + self.f.write(b'\x24\x80\x00\x00') # Chunk size (2084) + self.f.write(b'WAVE') + + # Fmt subchunk + self.f.write(b'fmt ') + self.f.write(b'\x10\x00\x00\x00') # Subchunk size (16 bytes) + self.f.write(b'\x01\x00') # Audio format (0x0001 == PCM) + self.f.write(b'\x02\x00') # Number of channels (2) + self.f.write(b'\x44\xac\x00\x00') # Samplerate (44100) + self.f.write(b'\x88\x58\x01\x00') # Byterate (88200) TODO + self.f.write(b'\x04\x00') # Blockalign (4) + self.f.write(b'\x10\x00') # Bits per sample (16) + + # Data subchunk + self.f.write(b'data') + self.f.write(b'\xff\xff\x00\x00') # Subchunk size (65535 bytes) TODO + + self.f.flush() + + def decode(self, ss, es, data): + ptype, pdata = data + + if ptype != 'DATA': + return + + channel, sample = pdata + + if self.wrote_header == False: + self.write_wav_header() + self.wrote_header = True + + # Output the next sample to 'filename'. + # TODO: Data: first left channel, then right channel. + if self.f != None: + # TODO: This currently assumes U32 samples, and converts to S16. + s = sample >> 16 + if s >= 0x8000: + s -= 0x10000 + lo, hi = s & 0xff, (s >> 8) & 0xff + self.f.write(bytes('%02x%02x' % (lo, hi), 'utf-8')) + self.f.flush() + -- cgit v1.2.3-70-g09d2