Hi Joe,
die absoluten Dateipositionen möchte ich nicht länger verwenden.
Wie beim Media Player, VLC Player… möchte ich die Zeit als Kriterium benutzen.
Teilweise hatte ich das schon geändert:
bool Audio::setAudioPlayTime(uint16_t sec); springt zur absoluten Zeitmarke
bool Audio::setTimeOffset(int sec); springt relativ um die augenblickliche Zeitmarke
uint32_t Audio::stopSong(); gibt die augenblickliche Zeitmarke zurück (in Sekunden)
uint32_t Audio::getAudioFileDuration(); Gesamtspieldauer (in Sekunden)
uint32_t Audio::getAudioCurrentTime(); Augenblickliche Zeitmarke (in Sekunden)
Wenn die Datei abgespielt wird sollte das immer funktionieren, unabhängig von der Quelle (Web, SD, SPIFFS…)
Dann natürlich noch bool Audio::pauseResume(); zum Anhalten und Fortsetzen
Schwierig wird es die Zeitposition beim Start einer Datei zu setzen.
Wenn die Audiodatei Informationen über die nominelle Bitrate oder die Gesamtspieldauer enthält ist das möglich
Also:
mp3 wenn es mpeg1 LayerIII ist gibt es fast immer einen Xing oder Info Header → okay
flac es gibt fast immer in BITSTREAMINFO den Wert totalSamplesInStream → okay
m4a es gibt fast immer ein mdhd Atom welches den Tag04 enthält → okay
In diesen Fällen, also bei fast allen neueren Dateien (flac, mp3, m4a) geht dann
bool Audio::connecttoFS(fs::FS& fs, const char* path, int32_t fileStartTime = -1); in fileStartTime Werte > 0 … < Gesamtspieldauer
Bei allen anderen muss die Datei erst gestartet wenden, dann ist nach kurzer Zeit die mittlere Bitrate bekannt und du kannst setAudioPlayTime() anwenden.
P.S.
Die „weak compiler bindings“ (wie audio_info(const char* info){}) habe ich durch „functional callbacks“ ersetzt. Das ist moderner und etwas einfacher anzuwenden
Im setup() setzt du eine Zeiger auf die Callback Funktion
Audio::audio_info_callback = my_audio_info; // Name frei vergebbar
und dann in CB:
void my_audio_info(Audio::msg_t m) {
switch(m.e){
case Audio::evt_info:
…
}
Das sind die Events in m.e (zur Unterscheidung)
typedef enum {evt_info = 0, evt_id3data, evt_eof, evt_name, evt_icydescription, evt_streamtitle, evt_bitrate, evt_icyurl, evt_icylogo, evt_lasthost, evt_image, evt_lyrics, evt_log} event_t;
in m.msg steht ein kurzer Text wie „SampleRate (Hz): 48000“
in m.arg1 steht der Wert als Integer also 48000
in m.s der EventName als const char*
in m.i2s_num der I2S Kanal
in m.vec der BildVektor (wie bisher APIC, Segment, Anfang, Ende)
Hoffe, das ist hilfreich für euer Projekt
vG
Wolle