Moin!
Im letzten Post habe ich über SPI einfach fertige PCM - Werte aus dem Speicher des VS1053 gelesen, die 16 Bit Werte mit dem vom Hersteller vorgeschlagenen Code (weil die Formel zu teuer ist um sie anzuwenden) nach dB umgewandelt und dann angezeigt.
Wer das Beispiel durch Aktivieren von USE_INTERNAL_VU_METER in der global.h schon ausprobiert hat, wird sehen das der Datenpuffer sich deutlich langsamer füllt als ohne VU Meter.
Es muss in der player_run immer erst ein Zeiger in den Speicher des VS1053 gesetzt werden und dann wird das PCM - Sample ausgelesen. Das zweimal für Links und Rechts. Dann die Konvertierung nach dB.
Wesentlich schneller geht es wenn man die Sache direkt über eine App im VS_DSP Kern des VS1053 berechnen lässt und nur das fertige Ergebnis abholt.
Screenshot 2024-04-26 at 10-19-12 VS1053 Datasheet - vs1053.pdf.png (Größe: 28,1 KB / Downloads: 136)
Der Hersteller bietet dazu kostenlos ein Entwicklungssystem was sich VSIDE nennt.
https://www.vlsi.fi/en/support/software/vside.html
VSDSP Application Development Environment
VSIDE is a full-featured application development suite for VSDSP signal processors
Familiar, user-friendly interface
Several sample projects to build upon
A complete set of utilities, including ANSI-C compiler, assembler, linker, profiler etc.
Supports emulator-based debugging using real hardware
Easy to get started, yet powerful and flexible
Ich empfehle das unbedingt mal anzusehen und auszuprobieren. Es gibt genug Tutorials beim Hersteller und im Web.
Im Forum
http://www.vsdsp-forum.com/phpbb/index.php sind viele Mitarbeiter der finnischen Firma VLSI aktiv und geben Unterstützung in den unterschiedlichsten Bereichen.
Wenn man sich mal tiefer in den Chip und das VSOS Operating System eingelesen hat, sieht man diese DSP Reihe nochmal mit ganz anderen Augen und bekommt viele Ideen die man direkt auf VS10xx umsetzen könnte.
https://www.vlsi.fi/en/support/applicationnotes.html
Die Programme für den VS10xx die der VSIDE Compiler ausspuckt, das können Patches bekannter ROM-Funktionen, neue Codecs oder eigene Anwendungen sein, können über verschiedene Wege auf den DSP ausgespielt werden!
Auf der Seite
https://www.vlsi.fi/en/support/software.html findet man zahlreiche interessante Sachen.
Für unser VU-Meter Problem von oben gibt es im VS1053b Patches w/ FLAC Decoder von
https://www.vlsi.fi/en/support/software/...tches.html eine Lösung.
VS1053b Patches w/ FLAC Decoder
- [i]Five versions of the patch included. With and without LATM/LOAS parser and with and without a FLAC (Free Lossless Audio Codec) decoder (1-2 channels, up to 24 bits, up to 48kHz) decoder, and with a pitch/tempo shifter.[/i]
- [i]VU meter (now with 1dB resolution) and other features, see the full list from the document.[/i]
- [i]Patches, among other things, the following:
[/i]- [i]AAC: Unused data at the start of the mdat atom in MP4 is now skipped. (Some NERO versions generated extra data there.)[/i]
- [i]HE-AAC: When parametric stereo (PS) is active, PS header frame was required to be present in the first encountered SBR frame or the decoding could crash. This patch fixes the problem.[/i]
- [i]Vorbis: Removes an occasional windowing overflow from Vorbis decoding and thus increases playback quality.[/i]
- [i]Ogg: Enables playing of Ogg streams that have the highest bit set in the stream number.[/i]
- [i]IMA ADPCM: Enables also data transfer when IMA encoding mode is started.[/i]
- [i]AAC: PNS of left channel could get corrupted during transition frames.[/i]
- [i]AAC: crc now ignored correctly for ADTS format files.[/i]
- [i]AAC: MP4 fixes.[/i]
- [i]FLAC: sets DO_NOT_JUMP during header.[/i]
- [i]HE-AACv2: slightly faster decoding.[/i]
- [i]Also contains the functionality of the old "VS1053b Ogg Vorbis Decoder Patch": sample counter and sample rate fine tuning.[/i]
- [i]15/16 Resampler allows samplerate tuning 'above 48kHz' even with 12.288MHz XTALI. Now can be automatically enabled only for 48kHz.[/i]
- [i]ID3 tag parser skips the tag data, so that binary data inside the tag is not erroneously interpreted as audio.[/i]
- [i]Can disable zero-sample insertion when out of stream data.[/i]
- [i]Experimental DSD64 decoder (.dff and .dsf)[/i]
- [i]Mono downmix mode for encoding.[/i]
Ich habe die Sammlung auch ins iRadioPico Repo gestellt
https://github.com/BM45/iRadioPico/blob/...hes290.zip
Wenn man die Datei (oder generell solche Programmpakete) entpackt, ergibt sich so ein Gefüge.
Die PDF enthält immer eine sehr gute Beschreibung des Paketes, wie der Code in den DSP geladen wird, verschiedenen Tools zum externen Laden und die Patches/Apps selbst.
Dabei gibt es zwei Dateiformate. Ein altes (unkomprimiertes Format) und ein neues komprimiertes Format.
Das alte Format besteht aus zwei Arrays atab und dtab.
Im atab sind die Speicheradressen enhalten wohin das dazu passende dtab - Element im Chip geschrieben werden muss. Wer so einen Patch im alten Format öffnet, sieht das das atab-Array ziemlich redundant ist. Beispiele findet man in den .c Dateien im Softwarepaket.
Weil das so ist, kann man diese Information komprimieren und man erhält das neue Format, die .plg Dateien im Softwarepaket.
screen2.jpg (Größe: 65,52 KB / Downloads: 132)
Vergleich .c zu .plg , man spart fast die Hälfte ein.
In den .c und .plg Dateien wird auch immer schon ein generischer Code zum Laden der Software in den DSP mitgegeben.
Das findet man immer am Anfang der Dateien mit dem alten Format, man beachtet mein Gesagtes atab <- dtab
Code:
/* VS1053b vorbis patch */
#if 0
void LoadUserCode(void) {
int i;
for (i=0;i<CODE_SIZE;i++) {
WriteVS10xxRegister(atab[i], dtab[i]);
}
}
#endif
Im neuen Format ist am Dateianfang immer dieser Code zugegeben
Code:
/* User application code loading tables for VS10xx */
#if 0
void LoadUserCode(void) {
int i = 0;
while (i<sizeof(plugin)/sizeof(plugin[0])) {
unsigned short addr, n, val;
addr = plugin[i++];
n = plugin[i++];
if (n & 0x8000U) { /* RLE run, replicate n samples */
n &= 0x7FFF;
val = plugin[i++];
while (n--) {
WriteVS10xxRegister(addr, val);
}
} else { /* Copy run, copy n samples */
while (n--) {
val = plugin[i++];
WriteVS10xxRegister(addr, val);
}
}
}
}
#endif
Wer also Software für den DSP entwickelt bekommt immer auch den generischen Code zum Laden mit und er braucht nur noch die Schreib/Lesefunktionen wie WriteVS10xxRegister ... auf seinem speziellen Mikrocontroller zu portieren. In der Arduino Umgebung wurde das aber schon gemacht und die von uns benutzte Adafruit_VS1053 Lib hat den Code für das Laden des neuen Formats in diesen zwei Funktionen drin:
/*!
* @brief Apply a code patch
* @param patch Patch to apply
* @param patchsize Patch size
*/
void applyPatch(const uint16_t *patch, uint16_t patchsize);
/*!
* @brief Load the specified plug-in
* @param fn Plug-in to load
* @return Either returns 0xFFFF if there is an error, or the address of the
* plugin that was loaded
*/
uint16_t loadPlugin(char *fn);
Mit loadPlugin kann man einen Patch einfach auf eine angeschlossene SD-Karte spielen und laden lassen (mit zwei Codezeilenänderungen) geht auch das LittleFS im Controller selbst.
Mit applyPatch schreibt man die Binärversion der DSP-Software aus dem Array der .plg Dateien ins System. Und so machen wir das auch.
Ich habe die .plg - Datei des Softwarepakets bereits mit wenigen Handgriffen in die Headerdatei vs1053b_patches.h überführt. Den generischen Einlesecode rausgeschmissen weil wir ihn ja nicht brauchen, was zusätzlich Platz im Flash frei lässt.
https://github.com/BM45/iRadioPico/blob/..._patches.h
Im Player des iRadioPico wird im Init-Teil, wenn VS1053 in der globals.h aktiv und USE_VLSI_VSDSP_VU_METER gesetzt, dieser Usercode in den VS1053 transferiert. Zusätzlich schalte ich mit Bit 9 im SCI_STATUS Register die VU-Meter App an. Das ist in diesem Paket der "Doppelklick auf das ausführbare Programm".
Code:
#ifdef USE_VLSI_VSDSP_VU_METER
// load vs1053 apps and patches from vs1053b_patches.h
VS1053Dekoder.applyPatch(plugin, PLUGIN_SIZE);
/*VU Meter -SCI_STATUS bit 9 enables VU meter, which calculates a leaking peak sample value
from both channels and returns the values in 1 dB resolution through SCI_AICTRL3.
The high 8 bits represent the left channel, the low 8 bits the right channel */
VS1053Dekoder.sciWrite(0x01, VS1053Dekoder.sciRead(0x01) | (1<<9) ); // SCI_STATUS(0x01)
#endif
Im Runner des Player wird dann nur noch das SCI_AICTRL3 Register mit den beiden auf dem VS_DSP berechneten Werten gelesen und für die PlayerInfo-Struktur bereitgestellt. Im Democode für das ILI9341 wird dann das VU-Meter mit dieser Information gezeichnet.
Das Nachladen des Puffers läuft nun deutlich schneller, weil wir Rechenarbeit auf den VS1053 selbst ausgelagert haben, hier ein Video (Audio stummgeschaltet wegen Copyright) zu sehen.
https://youtube.com/shorts/MLZu73s7W9A
*Da das Video wohl so kurz ist, hat Youtube daraus ein Shorts gemacht und diese Video-URLs können über den Player hier in der Forensoftware im Moment wohl nicht eingebettet werden, deshalb bitte den Videolink anklicken.