From 422610c21c08f455b7767e17a57e7d8931a81a69 Mon Sep 17 00:00:00 2001 From: kazu Date: Sun, 28 Feb 2021 20:44:01 +0100 Subject: [PATCH] many many small changes switched to the new logging here and there some cleanups worked on i2S base class for files id3 parsing --- Platforms.h | 15 ++- data/formats/avi/Demuxer.h | 10 +- data/formats/avi/structs.h | 2 +- data/formats/mp3/ID3.h | 246 +++++++++++++++++++----------------- ext/lcd/ILI9486p.h | 9 ++ ext/sd/AccessHelper.h | 1 + ext/sd/File.h | 17 +++ ext/sd/SDCard.h | 10 +- ext/sd/fat32/DirHandle.h | 2 +- ext/sd/fat32/FS.h | 4 + ext/sd/fat32/File.h | 8 +- ext/sd/main.cpp | 130 ++++++++++++++----- ext/sd/tests/TestCreate.cpp | 8 +- io/GPIO.h | 6 +- io/SoftI2C.h | 20 +-- io/SoftSPI.h | 6 +- io/teensy/I2S2.h | 6 +- io/teensy/I2SBaseDMA.h | 4 +- 18 files changed, 307 insertions(+), 197 deletions(-) create mode 100644 ext/sd/File.h diff --git a/Platforms.h b/Platforms.h index ccaf83e..4a1d327 100644 --- a/Platforms.h +++ b/Platforms.h @@ -1,4 +1,5 @@ - +#include +#include #define WEMOS_D1_MINI 1 #define NODE_MCU 2 @@ -13,28 +14,28 @@ #define DESKTOP 99 -#define ESP8266 (PLATFORM == WEMOS_D1_MINI) || (PLATFORM == NODE_MCU) -#define ESP32 (PLATFORM == WROOM32_DEVKIT) || (PLATFORM == TTGO) -#define TEENSY (PLATFORM == TEENSY_41) +#define IS_ESP8266 (PLATFORM == WEMOS_D1_MINI) || (PLATFORM == NODE_MCU) +#define IS_ESP32 (PLATFORM == WROOM32_DEVKIT) || (PLATFORM == TTGO) +#define IS_TEENSY (PLATFORM == TEENSY_41) #define IS_DESKTOP (PLATFORM == DESKTOP) #ifndef PLATFORM #error "PLATFORM compile time variable not defined" #endif -#if (ESP32) +#if (IS_ESP32) #pragma message "Using ESP32" #define DELAY_US(us) ets_delay_us(us) #define IN_FLASH -#elif (ESP8266) +#elif (IS_ESP8266) #pragma message "Using ESP8266" #define DELAY_US(us) os_delay_us(us) #define IN_FLASH ICACHE_FLASH_ATTR -#elif (TEENSY) +#elif (IS_TEENSY) #pragma message "Using Teensy" #define DELAY_MS(ms) delay(ms) diff --git a/data/formats/avi/Demuxer.h b/data/formats/avi/Demuxer.h index 79ddd63..8d23521 100644 --- a/data/formats/avi/Demuxer.h +++ b/data/formats/avi/Demuxer.h @@ -20,9 +20,9 @@ namespace AVI { NextChunk(NextChunkType type, uint32_t size) : type(type), size(size) {} }; - template class Demuxer { + template class Demuxer { - Source& src; + DataSource& src; bool valid = true; //AVITypeHeader riff; @@ -52,7 +52,7 @@ namespace AVI { public: - Demuxer(Source& src) : src(src) { + Demuxer(DataSource& src) : src(src) { RIFFHeader riff; read(riff); @@ -180,8 +180,8 @@ namespace AVI { void dumpState() { - std::cout << "video @" << state.video.streamID << ": " << state.video.fmt.bmi_header.biWidth << "x" << state.video.fmt.bmi_header.biHeight << " Format: " << state.streamHeaders[state.video.streamID].fccHandler.chars << std::endl; - std::cout << "audio @" << state.audio.streamID << ": " << state.audio.fmt.channels << " channels @ " << state.audio.fmt.samples_per_sec << " Hz" << " Format: " << state.audio.fmt.format_tag << std::endl; + //std::cout << "video @" << state.video.streamID << ": " << state.video.fmt.bmi_header.biWidth << "x" << state.video.fmt.bmi_header.biHeight << " Format: " << state.streamHeaders[state.video.streamID].fccHandler.chars << std::endl; + //std::cout << "audio @" << state.audio.streamID << ": " << state.audio.fmt.channels << " channels @ " << state.audio.fmt.samples_per_sec << " Hz" << " Format: " << state.audio.fmt.format_tag << std::endl; } AVIList readUntilList(const char* content) { diff --git a/data/formats/avi/structs.h b/data/formats/avi/structs.h index 60f1cbe..106172e 100644 --- a/data/formats/avi/structs.h +++ b/data/formats/avi/structs.h @@ -14,7 +14,7 @@ union FOURCC { bool operator == (const FOURCC other) const {return u32 == other.u32;} bool operator != (const FOURCC other) const {return u32 != other.u32;} -}; +} __attribute__((__packed__)); //struct AVICommonHeader { diff --git a/data/formats/mp3/ID3.h b/data/formats/mp3/ID3.h index 60e93fb..1b66cbb 100644 --- a/data/formats/mp3/ID3.h +++ b/data/formats/mp3/ID3.h @@ -1,14 +1,21 @@ #pragma once #include -#include #include +#include +#include + +#include + +#include "../../../Debug.h" /** * very basic ID3v2 reader * https://id3.org/id3v2.3.0#ID3v2_overview */ -template class ID3v2 { +class ID3v2 { + + static constexpr const char* NAME = "ID3v2"; /** 4 byte size, used to correct endianness */ struct Size { @@ -34,173 +41,176 @@ template class ID3v2 { bool isPadding() const {return name[0] == 0x00 && size == 0;} } __attribute__((packed)); - File& f; + static constexpr const uint8_t ENC_ISO8859 = 0x00; + static constexpr const uint8_t ENC_UNICODE = 0x01; + static constexpr const uint8_t ENC_UTF8 = 0x03; + + // maximum size for a frame to be read + static constexpr const uint32_t MAX_FRM_SIZE = 65536; public: - /** ctor, define whether to read contained images */ - ID3v2(File& f, bool includeImages) : f(f) { - read(includeImages); - } + struct Image { + bool present = false; + std::string mime; + uint8_t type; + std::string desc; + uint32_t pos; // the absolute position within the data where the image is + uint32_t size; // the length of the image in bytes + }; - /** parsed data */ struct Data { - std::string album; + bool ok = false; std::string artist; std::string title; + std::string album; std::string year; - std::vector image; - } data; + Image img; + }; -private: +public: - bool read(bool includeImages) { + ID3v2() {} - // start at beginning of file - seekTo(0); + template Data readTags(DataSource& src, bool readImages) { + + Data data; + + // start at beginning + src.seekTo(0); // 10 byte ID3 header, file starts with "ID3" ? Header head; - read(head); - if (memcmp(head.ID3, "ID3", 3) != 0) {return false;} - std::cout << head.size() << std::endl; + src.readType(head); + if (memcmp(head.ID3, "ID3", 3) != 0) {return data;} // read all tags - while(curPos() < head.size()) { + while(src.curPos() < head.size()) { Frame frm; - read(frm); - uint32_t startOfData = curPos(); - - std::cout << frm.name << ":" << frm.size << std::endl; + src.readType(frm); + uint32_t startOfData = src.curPos(); if (frm.isPadding()) { break; // only (empty) padding blocks will follow -> stop } else if (frm == "TALB") { - data.album = readString(frm.size); + data.album = readString(src, frm.size); } else if (frm == "TPE1") { - data.artist = readString(frm.size); + data.artist = readString(src, frm.size); } else if (frm == "TIT2") { - data.title = readString(frm.size); + data.title = readString(src, frm.size); } else if (frm == "TYER") { - data.year = readString(frm.size); - } else if (frm == "APIC" && includeImages) { - data.image = readImage(frm.size); + data.year = readString(src, frm.size); + } else if (frm == "APIC" && readImages) { + data.img = parseImage(src, frm.size); } + Log::addInfo(NAME, "%c%c%c%c:%d", frm.name[0],frm.name[1],frm.name[2],frm.name[3], (uint32_t)frm.size); + // ensure we are positioned after the frame - seekTo(startOfData + frm.size); + src.seekTo(startOfData + frm.size); } - return true; + data.ok = true; + return data; } private: - /** read a string with the given length, also corrects encoding */ - std::string readString(uint32_t size) { + /** read a string with the given length, corrects encoding */ + template std::string readString(DataSource& src, uint32_t size) { // read no more than 120 chars uint8_t buf[128]; - size = std::min(120u, size); - f.read(size, buf); + size = std::min((uint32_t)120, size); + src.read(size, buf); + if (buf[0] == ENC_ISO8859 || buf[0] == ENC_UTF8) { + return std::string((const char*) &buf[1]); + } else if (buf[0] == ENC_UNICODE) { // 16(!) bit unicode, starts with {0x01 0xFF 0xF4} + uint32_t pos = 0; + for (uint32_t i = 3; i < size; i += 2) { + buf[pos++] = buf[i]; + } + buf[pos] = 0; + return std::string((const char*)buf); + + } else { + return "ENCODING?"; + + } + + } + + /** read a string with an unknown length, zero termined, corrects encoding, also returns the number of bytes read */ + template std::string readStringZeroTerm(DataSource& src, uint8_t encoding, uint32_t& bytesRead) { + + std::string res; + bytesRead = 0; + + if (encoding == ENC_ISO8859 || encoding == ENC_UTF8) { + char c; + while(true) { + src.readType(c); + if (c == 0) {break;} + res += c; + ++bytesRead; + } + + } else if (encoding == ENC_UNICODE) { // 16(!) bit unicode, starts with {0x01 0xFF 0xFE} + char c[2]; + src.readType(c); // skip 0xFF 0xFE + while(true) { + src.readType(c); + if (c[0] == 0 && c[1] == 0) {break;} + res += c[0]; + bytesRead += 2; + } + + } else { + return "ENCODING?"; + + } + + return res; } /** read X bytes into a vector */ - std::vector readVector(const uint32_t size) { + template std::vector readVector(DataSource& src, const uint32_t size) { std::vector res; res.resize(size); - read(size, res.data()); + src.read(size, res.data()); return res; } - /** read an image (is preceeded by mime type and description) */ - std::vector readImage(const uint32_t size) { - std::vector tmp = readVector(size); + /** + * parse an image tag + * image data is preceeded by mime type and description) + * the image is not actually read, but its offset within the data and its size are determined + */ + template Image parseImage(DataSource& src, const uint32_t size) { + + uint32_t read1, read2; + Image img; + + uint8_t encoding; + src.readType(encoding); + + img.mime = readStringZeroTerm(src, ENC_ISO8859, read1); + src.readType(img.type); + img.desc = readStringZeroTerm(src, encoding, read2); + + // determine the position and byte-size of the image + img.pos = src.curPos(); + img.size = size - 1 - read1 - 1 - read2; + img.present = true; + + return img; - return tmp; } - - -private: - -// class StringWrapper { - -// const uint8_t* src; -// const uint32_t len; - -// public: - -// StringWrapper(const uint8_t* src, const uint8_t len) : src(src), len(len) {} - -// StringWrapper(const std::vector& vec, uint32_t offset = 0) : src(vec.data()+offset), len(vec.size()-offset) {} - -// std::string get(uint32_t& outPos) const { - -// // encoding? -// if (src[0] == 0x00) { // ISO8859-15 -// return std::string((const char*) &buf[1]); - -// } else if (buf[0] == 0x01) { // 16(!) bit unicode, starts with {0x01 0xFF 0xF4} -// uint32_t pos = 0; -// for (uint32_t i = 3; i < size; i += 2) { -// buf[pos] = buf[i]; -// ++pos; -// } -// buf[pos] = 0; -// return std::string((const char*)buf); - -// } else { -// return "ENCODING?"; - -// } - -// } - -// /** determine the length of the string */ -// uint32_t len() const { - -// if (src[0] == 0x00) { // ISO8859-15 - - -// } else if (buf[0] == 0x01) { // 16(!) bit unicode, starts with {0x01 0xFF 0xF4} -// uint32_t pos = 0; -// for (uint32_t i = 3; i < size; i += 2) { -// buf[pos] = buf[i]; -// ++pos; -// } -// buf[pos] = 0; -// return std::string((const char*)buf); - -// } else { - -// } - -// }; - - /** current position within the file */ - uint32_t curPos() { - return f.curPos(); - } - - /** seek to a new position within the file */ - void seekTo(uint32_t pos) { - f.seekTo(pos); - } - - template void read(T& dst) { - read(sizeof(T), (uint8_t*) &dst); - } - - void read(uint32_t size, uint8_t* dst) { - f.read(size, dst); - } - - }; diff --git a/ext/lcd/ILI9486p.h b/ext/lcd/ILI9486p.h index 0e1679b..49e235e 100644 --- a/ext/lcd/ILI9486p.h +++ b/ext/lcd/ILI9486p.h @@ -189,6 +189,15 @@ public: } } + void fill(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { + setAddrWindow(x,y,w,h); + modeDATA(); + const uint32_t entries = uint32_t(w) * uint32_t(h); + for (uint32_t i = 0; i < entries; ++i) { + writeByte(color>>8); writeByte(color>>0); + } + } + /** draw 5-6-5 encoded input data */ void draw(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t* data) { setAddrWindow(x,y,w,h); diff --git a/ext/sd/AccessHelper.h b/ext/sd/AccessHelper.h index ba889d9..74a99f5 100644 --- a/ext/sd/AccessHelper.h +++ b/ext/sd/AccessHelper.h @@ -2,6 +2,7 @@ #include "Types.h" #include "../../Debug.h" +#include /** * wrapper class diff --git a/ext/sd/File.h b/ext/sd/File.h new file mode 100644 index 0000000..32aee44 --- /dev/null +++ b/ext/sd/File.h @@ -0,0 +1,17 @@ +#pragma once + +class File { + +public: + + virtual uint32_t size() const = 0; + + virtual uint32_t curPos() const = 0; + + virtual void seekTo(uint32_t pos) = 0; + + virtual uint32_t read(uint32_t size, uint8_t* dst) = 0; + + virtual uint32_t write(uint32_t size, const uint8_t* src) = 0; + +}; diff --git a/ext/sd/SDCard.h b/ext/sd/SDCard.h index ca218e2..dffc0bf 100644 --- a/ext/sd/SDCard.h +++ b/ext/sd/SDCard.h @@ -77,7 +77,7 @@ public: for (uint8_t i = 0; ; ++i) { const R1 res = cmd0(); if (res.raw == 1) {break;} - if (i == 4) {Log::addError(NAME, "init failed"); return false;} + if (i == 8) {Log::addError(NAME, "init failed"); return false;} delay(50); } @@ -309,7 +309,7 @@ private: // NOTE: it is IMPORTANT to send 0xFF to the card while reading its responses! // wait for the first byte to arrive and read it - for (uint8_t i = 0; i < 8; ++i) { + for (uint8_t i = 0; i < 32; ++i) { dst[0] = spi.readWriteByte(0xFF); if ( (dst[0] & 0x80) == 0 ) {break;} } @@ -328,6 +328,8 @@ private: /** most simple read operation: read a single block of 512 bytes, addr = byteAddr/512 */ bool readSingleBlock(LBA512 addr, uint8_t* dst) { + //spi.setSlowdown(0); + sendCMD(17, addr>>24, addr>>16, addr>>8, addr>>0, 0xFF); R1 res; readResponse(&res.raw, 1); @@ -341,7 +343,7 @@ private: uint8_t res = spi.readWriteByte(0xFF); if (res == 0xFE) {break;} // available! if (res != 0xFF) {Log::addError(NAME, "invalid"); endCMD(); return false;} // invalid response - if (i > 1024) {Log::addError(NAME, "timeout"); endCMD(); return false;} // timeout + if (i > 32768) {Log::addError(NAME, "timeout"); endCMD(); return false;} // timeout } // read data @@ -349,6 +351,8 @@ private: dst[i] = spi.readWriteByte(0xFF); } + //spi.setSlowdown(128); + // done endCMD(); return true; diff --git a/ext/sd/fat32/DirHandle.h b/ext/sd/fat32/DirHandle.h index be1a064..8fcd579 100644 --- a/ext/sd/fat32/DirHandle.h +++ b/ext/sd/fat32/DirHandle.h @@ -75,7 +75,7 @@ namespace FAT32 { bool hasExtension(const char* ext) const { const size_t len = strlen(ext); if (len > 3) {return false;} - for (int i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) { if (asciitolower(entry.ext[i]) != asciitolower(ext[i])) {return false;} } for (int i = len; i < 3; ++i) { diff --git a/ext/sd/fat32/FS.h b/ext/sd/fat32/FS.h index f431e83..59d963c 100644 --- a/ext/sd/fat32/FS.h +++ b/ext/sd/fat32/FS.h @@ -7,6 +7,10 @@ #include "Structs.h" #include "DirHandle.h" +#include "../../../Debug.h" + +#include "../File.h" + // https://www.pjrc.com/tech/8051/ide/fat32.html namespace FAT32 { diff --git a/ext/sd/fat32/File.h b/ext/sd/fat32/File.h index e89dd50..95d9136 100644 --- a/ext/sd/fat32/File.h +++ b/ext/sd/fat32/File.h @@ -1,4 +1,4 @@ -class File { +class File : public ::File { static constexpr const char* NAME = "FAT32_File"; static constexpr const uint32_t F_EOF = 0xFFFFFFFF; @@ -20,7 +20,7 @@ public: } /** the file's USED size */ - uint32_t getSize() const {return h.getSize();} + uint32_t size() const {return h.getSize();} /** the file's ALLOCATED size */ uint32_t getAllocatedSize() const {return clusters.size() * fs.tmp.bytesPerCluster;} @@ -124,7 +124,7 @@ private: int32_t _read(uint32_t readSize, uint8_t* dst) { // EOF reached? - if (curAbsPos >= getSize()) { + if (curAbsPos >= size()) { return F_EOF; } @@ -185,7 +185,7 @@ private: curAbsPos += written; // adjust the number of bytes used - if (this->getSize() < curAbsPos) {this->setSize(curAbsPos);} + if (this->size() < curAbsPos) {this->setSize(curAbsPos);} return written; diff --git a/ext/sd/main.cpp b/ext/sd/main.cpp index 4a39919..29ec696 100644 --- a/ext/sd/main.cpp +++ b/ext/sd/main.cpp @@ -15,6 +15,8 @@ #include "fat32/FS.h" #include "AccessHelper.h" +#include "../../data/formats/DataSourcePosixFile.h" + #include #include @@ -76,34 +78,7 @@ public: }; -class SimuFile { - FILE* f; - -public: - - SimuFile(const char* image) { - f = fopen(image, "rw"); - if (!f) {throw std::runtime_error("failed to open");} - } - - uint32_t curPos() const { - return ftell(f); - } - - void seekTo(uint32_t pos) { - fseek(f, pos, SEEK_SET); - } - - uint32_t read(uint32_t bytes, uint8_t* dst) { - return fread(dst, bytes, 1, f) * bytes; - } - - uint32_t write(uint32_t bytes, const uint8_t* src) { - return fwrite(src, bytes, 1, f) * bytes; - } - -}; #include @@ -117,18 +92,83 @@ public: #include "/apps/ESP8266lib/data/formats/jpeg/JPEGDEC.cpp" //#include "/apps/ESP8266lib/data/formats/jpeg/jpeg.c" + +#define MINIMP3_ONLY_MP3 +#define MINIMP3_NO_SIMD +#define MINIMP3_IMPLEMENTATION +#include "/apps/ESP8266lib/data/formats/mp3/minimp3.h" + +#include "/apps/ESP8266lib/data/formats/mp3/ID3.h" + int drawJPEG(JPEGDRAW* pDraw) { return 1; } +ID3v2::Image mp3Image; +DataSourcePosixFile mp3DS; + int main(int argc, char** argv) { - if (1==0) { - // ffmpeg -i '/mnt/ssss/anime/Toaru Majutsu no Index/[Eclipse] Toaru Majutsu no Index - 07 (1280x720 h264) [0255D83A].mkv' -r 15 -ss 30 -vf scale=480x320 -c:v mjpeg -c:a mp3 -ar 44100 /tmp/ram/1.avi + if (1==1) { + //SimuFile simu("/mnt/ssss/mp3s/TronLegacy/Tron Legacy Remixe/Daft Punk - The Son Of Flynn (Daniel En Test Remix).mp3"); + //DataSourcePosixFile f("/mnt/ssss/mp3s/grooveshark/2 Sonic feat. Destiny - Straight To The Light (Bass Up Remix).mp3"); + //DataSourcePosixFile f("/mnt/ssss/mp3s/MP3s/Scooter/Scooter - How Much Is The Fish.mp3"); + DataSourcePosixFile f("/mnt/ssss/mp3s/newretrowave/Daniel Deluxe - Soul Siphon.mp3"); + //DataSourcePosixFile f("/mnt/ssss/mp3s/F-777/Kr1z & F-777/ReMotion Vol.2/Kr1z & F-777 - Frozen Words (Kr1z Remix).mp3"); - SimuFile simu("/tmp/ram/1.avi"); - AVI::Demuxer demux(simu); + + + ID3v2 id3; + ID3v2::Data data = id3.readTags(f, true); + + if (data.img.present) { + + mp3DS = f; + mp3Image = data.img; + JPEGDEC jpeg; + + auto open = [] (const char* filename, int32_t* size) -> void* { + *size = mp3Image.size; + mp3DS.seekTo(mp3Image.pos); + return (void*)1; + }; + auto close = [] (void*) { + return; + }; + auto read = [] (JPEGFILE* pFile, uint8_t* pBuf, int32_t iLen) -> int32_t { + const uint32_t got = mp3DS.read(iLen, pBuf); + return got; + }; + auto seek = [] (JPEGFILE *pFile, int32_t iPosition) { + mp3DS.seekTo(iPosition + mp3Image.pos); + return 1; + }; + auto draw = [] (JPEGDRAW *pDraw) { + std::cout << pDraw->x << ":" << pDraw->y << " " << pDraw->iWidth << ":" << pDraw->iHeight << std::endl; + return 1; + }; + + + if (jpeg.open("img", open, close, read, seek, draw)) { + jpeg.setPixelType(RGB565_BIG_ENDIAN); + jpeg.decode(0, 0, 0);//40, 100, JPEG_SCALE_QUARTER | JPEG_EXIF_THUMBNAIL); + jpeg.close(); + } + + printf("xx"); + + } + + + } + + if (0==1) { + + // ffmpeg -i '/mnt/ssss/anime/Toaru Majutsu no Index/[Eclipse] Toaru Majutsu no Index - 07 (1280x720 h264) [0255D83A].mkv' -r 15 -ss 30 -t 30 -vf scale=480x320 -c:v mjpeg -c:a mp3 -ar 44100 /tmp/ram/1.avi + + DataSourcePosixFile f("/tmp/ram/1.avi"); + AVI::Demuxer demux(f); bool valid = demux.isValid(); std::cout << "valid: " << valid << std::endl; @@ -136,10 +176,20 @@ int main(int argc, char** argv) { uint8_t buf[64*1024]; std::ofstream outV("/tmp/ram/1.mjpeg"); - std::ofstream outA("/tmp/ram/1.mp3"); + std::ofstream outA1("/tmp/ram/1.mp3"); + std::ofstream outA2("/tmp/ram/1.pcm"); JPEGDEC jpeg; + mp3dec_t mp3d; + mp3dec_frame_info_t info; + info.frame_bytes = 0; + mp3dec_init(&mp3d); + short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; + + // ffplay /tmp/ram/1.mp3 + // ffplay -autoexit -f s16le /tmp/ram/1.pcm + for (int i = 0; i < 1024; ++i) { AVI::NextChunk nc = demux.getNextChunk(); @@ -148,7 +198,8 @@ int main(int argc, char** argv) { demux.read(nc, buf); if (nc.type == AVI::NextChunkType::VIDEO) { - outV.write((const char*)buf, nc.size); + + //outV.write((const char*)buf, nc.size); int res = jpeg.openRAM(buf, nc.size, drawJPEG); std::cout << "jpeg: " << res << std::endl; @@ -159,7 +210,16 @@ int main(int argc, char** argv) { } } else if (nc.type == AVI::NextChunkType::AUDIO) { - outA.write((const char*)buf, nc.size); + + outA1.write((const char*)buf, nc.size); + + uint32_t samples = mp3dec_decode_frame(&mp3d, buf, nc.size, pcm, &info); + + std::cout << nc.size << " : " << info.frame_bytes << std::endl; + + outA2.write((const char*)pcm, samples*2*sizeof(int16_t)); + + } @@ -207,7 +267,7 @@ int main(int argc, char** argv) { if (1==0) { uint8_t* bufff = (uint8_t*) malloc(1024*1024); - uint32_t read = f.read(f.getSize(), bufff); + uint32_t read = f.read(f.size(), bufff); std::string name = f.getName(); std::ofstream out("/tmp/ram/" + name); diff --git a/ext/sd/tests/TestCreate.cpp b/ext/sd/tests/TestCreate.cpp index 77074b8..5ae11d7 100644 --- a/ext/sd/tests/TestCreate.cpp +++ b/ext/sd/tests/TestCreate.cpp @@ -52,7 +52,7 @@ TEST (TestCreate, writeRead) { free(data); ASSERT_EQ(size, written); - ASSERT_EQ(size, f.getSize()); + ASSERT_EQ(size, f.size()); ASSERT_EQ(sizeA, f.getAllocatedSize()); } @@ -78,7 +78,7 @@ TEST (TestCreate, writeRead) { ASSERT_EQ(name, h.getName()); ASSERT_EQ(name, f.getName()); - ASSERT_EQ(size, f.getSize()); + ASSERT_EQ(size, f.size()); ASSERT_EQ(sizeA, f.getAllocatedSize()); uint8_t* data = (uint8_t*)malloc(128 + i * 512); @@ -159,7 +159,7 @@ TEST (TestCreate, getOrCreateFile) { ASSERT_EQ(size, fs.getSize()); FS::File f1 = fs.getOrCreateFile("test.txt"); - ASSERT_EQ(0, f1.getSize()); + ASSERT_EQ(0, f1.size()); ASSERT_EQ(4096, f1.getAllocatedSize()); ASSERT_EQ("test.txt", f1.getName()); @@ -171,7 +171,7 @@ TEST (TestCreate, getOrCreateFile) { FS::File f2 = fs.getOrCreateFile("test.txt"); - ASSERT_EQ(128, f2.getSize()); + ASSERT_EQ(128, f2.size()); ASSERT_EQ(128, f2.read(128, d2)); for (uint32_t i = 0; i < 128; ++i) {ASSERT_EQ(d1[i], d2[i]);} diff --git a/io/GPIO.h b/io/GPIO.h index 0fd9a17..0ca881e 100644 --- a/io/GPIO.h +++ b/io/GPIO.h @@ -4,7 +4,7 @@ #include "../Platforms.h" -#if ESP8266 +#if IS_ESP8266 #include "fastGPIO.h" @@ -94,7 +94,7 @@ }; -#elif ESP32 +#elif IS_ESP32 #include "driver/gpio.h" @@ -178,7 +178,7 @@ }; -#elif TEENSY +#elif IS_TEENSY struct MyGPIO { diff --git a/io/SoftI2C.h b/io/SoftI2C.h index 94b7eb4..b7d4ba8 100644 --- a/io/SoftI2C.h +++ b/io/SoftI2C.h @@ -49,7 +49,7 @@ template class SoftI2C { } void init() { - debugMod2(NAME, "init. SDA: %d, SCL: %d", PIN_SDA, PIN_SCL); + Log::addInfo(NAME, "init. SDA: %d, SCL: %d", PIN_SDA, PIN_SCL); } public: @@ -151,10 +151,10 @@ public: } inline void queryAll() { - debugMod(NAME, "queryAll()") + Log::addInfo(NAME, "queryAll()"); for (uint8_t i = 0; i < 128; ++i) { if (query(i)) { - debugMod1(NAME, "found %d", i) + Log::addInfo(NAME, "found %d", i); } waitLong(); if (i%16 == 0) {delay(10);} @@ -179,14 +179,14 @@ public: // select register(s) to read ok = startWrite(addr); - if (!ok) {debugMod(NAME, "failed start read(1)"); return false;} + if (!ok) {Log::addInfo(NAME, "failed start read(1)"); return false;} ok = writeByteAndCheck(reg); - if (!ok) {debugMod(NAME, "failed select register"); return false;} + if (!ok) {Log::addInfo(NAME, "failed select register"); return false;} stop(); // read register(s) ok = startRead(addr); - if (!ok) {debugMod(NAME, "failed start read(2)"); return false;} + if (!ok) {Log::addInfo(NAME, "failed start read(2)"); return false;} readBytes(dst, len); stop(); @@ -201,11 +201,11 @@ public: // address the slave in write mode and select the first register to read ok = startWrite(addr); - if (!ok) {debugMod(NAME, "failed start write"); return false;} + if (!ok) {Log::addInfo(NAME, "failed start write"); return false;} ok = writeByteAndCheck(reg); - if (!ok) {debugMod1(NAME, "failed to select register %d", addr); return false;} + if (!ok) {Log::addInfo(NAME, "failed to select register %d", addr); return false;} ok = writeBytesAndCheck(src, len); - if (!ok) {debugMod(NAME, "failed to write register contents"); return false;} + if (!ok) {Log::addInfo(NAME, "failed to write register contents"); return false;} // done stop(); @@ -322,7 +322,7 @@ namespace i2c { #if ESP8266 // static inline void init() { - // //debugMod(NAME, "init()"); + // //Log::addInfo(NAME, "init()"); // GPIO5_OUTPUT_SET; // clock is always output // //GPIO5_INPUT_PULLUP_SET; // pullup for i2c // //GPIO4_INPUT_PULLUP_SET; // pullup for i2c diff --git a/io/SoftSPI.h b/io/SoftSPI.h index 6346c5a..e1276b7 100644 --- a/io/SoftSPI.h +++ b/io/SoftSPI.h @@ -88,19 +88,19 @@ private: public: - void IRAM_ATTR writeQuad(const uint32_t quad) { + void writeQuad(const uint32_t quad) { writeByte((quad>>24)&0xFF); writeByte((quad>>16)&0xFF); writeByte((quad>> 8)&0xFF); writeByte((quad>> 0)&0xFF); } - void IRAM_ATTR writeWord(const uint16_t word) { + void writeWord(const uint16_t word) { writeByte((word>>8)&0xFF); writeByte((word>>0)&0xFF); } - inline void IRAM_ATTR writeByte(uint8_t byte) { + inline void writeByte(uint8_t byte) { writeBit(byte & BIT( 7)); writeBit(byte & BIT( 6)); writeBit(byte & BIT( 5)); diff --git a/io/teensy/I2S2.h b/io/teensy/I2S2.h index 6c26403..1537256 100644 --- a/io/teensy/I2S2.h +++ b/io/teensy/I2S2.h @@ -165,6 +165,8 @@ private: // init static class members #ifdef I2S2_IMPLEMENTATION - DMAMEM __attribute__((aligned(32))) int16_t I2S2::buffer[I2S2_BUFFER_SAMPLES]; - I2S2::State I2S2::state; + //template<> DMAMEM __attribute__((aligned(32))) int16_t I2SBase::buffer[I2S2_BUFFER_SAMPLES]; + //template<> I2SBase::State I2SBase::state; + DMAMEM __attribute__((aligned(32))) int16_t I2S2::buffer[I2S2_BUFFER_SAMPLES]; + I2S2::State I2S2::state; #endif diff --git a/io/teensy/I2SBaseDMA.h b/io/teensy/I2SBaseDMA.h index d491ba6..be79ab9 100644 --- a/io/teensy/I2SBaseDMA.h +++ b/io/teensy/I2SBaseDMA.h @@ -80,7 +80,9 @@ public: static void clearBuffer() { memset(buffer, 0, sizeof(buffer)); state.bufferHalf[0].samplesUsed = 0; + state.bufferHalf[0].dropCache(); state.bufferHalf[1].samplesUsed = 0; + state.bufferHalf[1].dropCache(); } /** block until the given number of samples were added to the internal buffer */ @@ -99,7 +101,7 @@ public: BufferHalf& bh = state.fillingHalf(); // determine how many samples to add - const uint16_t addable = min(numSamples, bh.samplesFree()); + const uint16_t addable = std::min(numSamples, bh.samplesFree()); // actually copy the data uint8_t* dst = (uint8_t*) (&bh.mem[bh.samplesUsed]);