Ja, gerne. Vielen Dank. Das interessiert mich sehr. Kann das in GPL Code übernommen werden?
Grüße,
Carsten
Ja, gerne. Vielen Dank. Das interessiert mich sehr. Kann das in GPL Code übernommen werden?
Hallo Carsten,carsten hat geschrieben: ↑Sa 10. Jul 2021, 23:04Radiotext bzw. RDS ist da bei HR, SWR und WDR, Radiotext fehlt aktuell bei BR, Radio Bremen, NDR. Es ist technisch anders implementiert als vorher (mp1/2: Teil des Audiostroms, acc-latm: Ein eigener MPEG-PES mit eigener PID die aber in der PMT mit einem "private use" stream-type (0x89) angekündigt wird).Radiofritze hat geschrieben: ↑Sa 10. Jul 2021, 18:54 Habe soeben mit meinen diversen Dreamboxen und VU+ Geräten getestet. Sämtliche Programme sind hörbar, aber soundmäßig zu MPEG 1 Layer II ein Unterschied wie zwischen Tag und Nacht. Ich hoffe, die ARD fixt den Sound noch entsprechend. Außerdem fehlt immer noch der Radiotext. Geht gar nicht!!!
IMHO ist die Audioqualität ok, auch auf der Stereoanlage. Mit dem Kopfhörer kann man zwar durchaus vereinzelt Artefakte ausmachen, mein letzter Hörtest war aber eher Anfang bis Mitte letzter Woche. Ich war so mutig und habe die hier oft gehörten Programme "Das Ding", "SWR1" und "SWR3" schonmal umgestellt da hier auch der Radiotext läuft.
Grüße,
Carsten
Hallo advtaco,advtaco hat geschrieben: ↑So 11. Jul 2021, 13:50Hallo Carsten,carsten hat geschrieben: ↑Sa 10. Jul 2021, 23:04Radiotext bzw. RDS ist da bei HR, SWR und WDR, Radiotext fehlt aktuell bei BR, Radio Bremen, NDR. Es ist technisch anders implementiert als vorher (mp1/2: Teil des Audiostroms, acc-latm: Ein eigener MPEG-PES mit eigener PID die aber in der PMT mit einem "private use" stream-type (0x89) angekündigt wird).Radiofritze hat geschrieben: ↑Sa 10. Jul 2021, 18:54 Habe soeben mit meinen diversen Dreamboxen und VU+ Geräten getestet. Sämtliche Programme sind hörbar, aber soundmäßig zu MPEG 1 Layer II ein Unterschied wie zwischen Tag und Nacht. Ich hoffe, die ARD fixt den Sound noch entsprechend. Außerdem fehlt immer noch der Radiotext. Geht gar nicht!!!
IMHO ist die Audioqualität ok, auch auf der Stereoanlage. Mit dem Kopfhörer kann man zwar durchaus vereinzelt Artefakte ausmachen, mein letzter Hörtest war aber eher Anfang bis Mitte letzter Woche. Ich war so mutig und habe die hier oft gehörten Programme "Das Ding", "SWR1" und "SWR3" schonmal umgestellt da hier auch der Radiotext läuft.
Grüße,
Carsten
bei BR, RB, NDR, RBB, MDR gibt es den Radiotext im AAC embedded.
Nicht so einfach zu extrahieren wie damals beim Layer II, aber bspw. der fdk-aac kann es decodieren.
Ich kann gerne Codebeispiele zur Verfügung stellen, wie man das RDS da rausbekommt
Grüße
Ok, diesen Check der beiden Descriptoren habe ich mit eingebaut und einen "Audio-Preference" Selektor eingebaut. Rangfolge ist MPEG, AAC-LATM, AAC, AC-3 (AC-3 als letztes weil das oft technische Probleme gibt, das kann man über einen Kommandoschalter/Environment vor MPEG schieben). Die AAC profile werden bewertet, so daß die 256 kBit/s Streams bevorzugt werden gegenüber den 128 kBit/s Streams. Bei MPEG wird die Bitrate nicht beachtet, dürfte in der Radiopraxis aber keine Rolle spielen. Es werden nur die von mir bis jetzt gesehenen AAC profile bewertet tut aber für den ARD Transponder was es soll.Basic.Master hat geschrieben: ↑So 11. Jul 2021, 00:12Ich weiß nicht, ob es das ist, was du mit "noch nicht ganz elegant" meinst: Aktuell prüfst du lediglich den Stream Type, wichtiger wäre dort aber der ancillary data descriptor, der letztendlich erst signalisiert, dass auf der PID RDS via UECP übertragen wird....ansonsten könnte es an der Stelle irgendwann mal zu False Positives kommen.
Wie es scheint, leider nicht, fdk-aac ist von der Lizenz nicht das wahre, ich kann aber mal schauen ob ich was finde, um nur die Ancillary-Daten aus dem Frame zu holen, ohne den Decoder zu brauchen.
Dann ist hier trotzdem mal das Beispiel, in C.Radiofritze hat geschrieben: ↑So 11. Jul 2021, 17:34 Hallo advtaco,
für viele Freaks hier im Forum wären die Codebeispiele sehr von Interesse.
Code: Alles auswählen
#include <string.h>
#include <unistd.h>
#include <fdk-aac/aacdecoder_lib.h>
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
static UINT getAacFrame(UCHAR *pBuffer, UINT bufferSize);
static void processAncDataFrame(UCHAR *pData, int size);
static int16_t loasReadFrameLength(uint8_t *pBuffer);
int main(void)
{
// Buffergroessen: - AAC-Buffer 4kB, damit auch das groesste Frame reinpasst
// - LPCM-Buffer 16384 Samples, entspricht 8 Kanaelen bei 2048 Samples/Frame (Standard fuer HE-AACv1/2)
// - Ancillary Data Buffer 1kB, das ist vermutlich ueberdimensioniert aber es sollte ja genug RAM verfuegbar sein
static UCHAR aacBuffer[4096] = { 0 };
static INT_PCM lpcmBuffer[16384] = { 0 };
static UCHAR ancDataBuffer[1024] = { 0 };
HANDLE_AACDECODER hAacDecoder = NULL;
CStreamInfo *pStreamInfo = NULL;
UINT frameLength = 0;
int rc = 0;
hAacDecoder = aacDecoder_Open(TT_MP4_LOAS, 1);
if (!hAacDecoder)
{
// Decoder konnte nicht initialisiert werden
return -1;
}
rc = aacDecoder_AncDataInit(hAacDecoder, ancDataBuffer, sizeof(ancDataBuffer));
if (rc < 0)
{
// Ancillary-Daten-Buffer konnte nicht initialisiert werden
goto cleanup;
}
// Initial ein Frame in den Buffer laden
frameLength = getAacFrame(aacBuffer, sizeof(aacBuffer));
while (1)
{
UCHAR *pBuffer = aacBuffer;
UINT bufferSize = sizeof(aacBuffer);
UINT bytesValid = frameLength;
int dseIdx = 0;
// Bitstream-Daten in den Decoder fuellen
rc = aacDecoder_Fill(hAacDecoder, &pBuffer, &bufferSize, &bytesValid);
if (rc != AAC_DEC_OK)
{
// Frame konnte nicht in Decoder geschrieben werden
usleep(10);
continue;
}
// Laut Dokumentation des Decoders sollte nach Moeglichkeit der Buffer nur dann nach-befuellt werden,
// wenn das vorherige Frame vollstaendig verarbeitet wurde.
if (bytesValid == 0)
{
frameLength = getAacFrame(aacBuffer, sizeof(aacBuffer));
}
else
{
memmove(aacBuffer, &(aacBuffer[frameLength - bytesValid]), bytesValid);
frameLength = bytesValid;
}
// Ein AAC-Frame decodieren
rc = aacDecoder_DecodeFrame(hAacDecoder, lpcmBuffer, ARRAY_SIZE(lpcmBuffer), 0);
if (rc == AAC_DEC_NOT_ENOUGH_BITS)
{
// Der Decoder hat noch nicht ausreichend Bitstream-Bytes erhalten.
// Das tritt in der Regel immer am Anfang auf, da nicht jedes Audio Frame
// einen LOAS-Header enthaelt.
usleep(10);
continue;
}
else if (rc != AAC_DEC_OK)
{
// Frame konnte nicht decodiert werden
usleep(10);
continue;
}
if (!pStreamInfo)
{
pStreamInfo = aacDecoder_GetStreamInfo(hAacDecoder);
if (pStreamInfo)
{
// Hier koennten Daten ueber den AAC-Strom abgeholt werden (bspw. Anzahl Samples pro Frame, Sample Rate, AOT, etc.)
}
}
// An dieser Stelle koennen die LPCM-Daten verarbeitet werden.
// Auch wenn die LPCM-Daten nicht gebraucht werden, muss trotzdem aacDecoder_DecodeFrame aufgerufen werden,
// da sonst keine Ancillary-Daten extrahiert werden.
// Ist nicht dokumentiert, aber im Quellcode der aacDecoder_AncDataGet-Funktion wird geprueft, ob
// der Index zwischen 0 und 8 ist, daher muss nur dieser Bereich abgedeckt werden.
for (dseIdx = 0; dseIdx < 8; dseIdx++)
{
UCHAR *pAncData = NULL;
int ancDataSize = 0;
// Keine Fehlerbehandlung, gibt in jedem Fall AAC_DEC_OK zurueck
aacDecoder_AncDataGet(hAacDecoder, dseIdx, &pAncData, &ancDataSize);
if (pAncData == NULL)
{
// Es kommen keine weiteren Ancillary Data Frames.
break;
}
processAncDataFrame(pAncData, ancDataSize);
}
usleep(10);
}
cleanup:
aacDecoder_Close(hAacDecoder);
return 0;
}
///
/// \brief Schreibt genau ein AAC-Frame in `pBuffer`. Soll blockieren, bis ein AAC-Frame
/// verfuegbar ist.
///
/// \param[in] pBuffer Der Buffer, in den das Frame geschrieben werden soll
/// \param[in] bufferSize Groesse des Buffers
///
/// \return Frame-Laenge in Byte
///
static UINT getAacFrame(UCHAR *pBuffer, UINT bufferSize)
{
/// \todo Implementieren
return 0;
}
///
/// \brief Kopiert die Ancillary-Daten aus `pData`, um verarbeitet zu werden.
///
/// \param[in] pData Die Ancillary-Daten
/// \param[in] size Anzahl der Bytes in `pData`
///
static void processAncDataFrame(UCHAR *pData, int size)
{
/// \todo Implementieren
// Auf den Inhalt von pData muss gesynct werden, hier sind aus irgendeinem Grund nicht nur UECP-Frames,
// sondern auch Fuellbytes, die natuerlich ignoriert werden muessen.
}
///
/// \brief Liest einen LOAS-Header und gibt die Laenge des Frames zurueck
///
/// \param[in] pBuffer Buffer, der das LOAS-Frame enthaelt
///
static int16_t loasReadFrameLength(uint8_t *pBuffer)
{
uint16_t syncWord = ((pBuffer[0] << 8) | (pBuffer[1] & 0xe0));
if (syncWord != 0x56e0)
return -1;
return ((((pBuffer[1] & 0x1f) << 8) | pBuffer[2]) + 3);
}
Vielen Dank für das Beispiel. fdk-aac ist das "non-Open-Licence" Fraunhofer-original. Der C-Code macht hier ja intensiven Gebrauch von Calls in die Library. In der offenen libavcodec gibts auch ein latm_decode_frame() (AAC funktioniert ja auch grundsätzlich), aber leider gibt es da (auf die Schnelle geguckt) keine Funktion um auf "ancillary"-Data zuzugreifen.
Code: Alles auswählen
[Mon Jul 12 21:36:24.524156 2021] [ts2shout:info] [pid 19829] add_payload_from_pmt(): Audio `AAC profile, Level 2'
[Mon Jul 12 21:36:24.524207 2021] [ts2shout:info] [pid 19829] add_payload_from_pmt(): stream language `deu'
[Mon Jul 12 21:36:24.524225 2021] [ts2shout:info] [pid 19829] add_payload_from_pmt(): Found HE-AAC audio stream in PID 401 (service_id 10432)
[Mon Jul 12 21:36:24.524241 2021] [ts2shout:info] [pid 19829] add_channel(): Subscribing to MPEG-TS PID 401 (Type CHANNEL_TYPE_PAYLOAD)
[Mon Jul 12 21:36:24.524258 2021] [ts2shout:info] [pid 19829] add_payload_from_pmt(): Found RDS data stream in PID 402
[Mon Jul 12 21:36:24.524272 2021] [ts2shout:info] [pid 19829] add_channel(): Subscribing to MPEG-TS PID 402 (Type CHANNEL_TYPE_RDS)
[Mon Jul 12 21:36:24.525130 2021] [ts2shout:info] [pid 19829] Synced to HE-AAC, Guessed Samplerate 48000 Hz, Bitrate 128 kBit/s
[Mon Jul 12 21:36:24.823743 2021] [ts2shout:info] [pid 19829] SDT: Stream is station SR 1 Europawelle from network ARD SR.
Mir ist heute zufällig ein alter Screenshot eines Blankom ASI -> UKW-Umsetzers in die Hände gefallen. Der zeigt die 3 Programme der FFH-Gruppe mit RDS via private PID:
Da ist was. Man findet es in der PMT von Hitradio FFH. Ich mußte hier auch den ganzen Transponder laden.Chris_BLN hat geschrieben: ↑Mo 12. Jul 2021, 23:00Ich habe die gleichen Umsetzer hier, nur mit DVB-S-Frontend. FFH hatte ich bislang nicht getestet, weil alle 30 Umsetzungen der 5 Umsetzer aktiv laufen.
Bei DLF Nova sollen auch irgendwelche Daten gesendet werden, jedoch soweit mir bekannt nicht im UECP-Format. Wer mag und kann, kann ja mal testen, ob und was da los ist.
Code: Alles auswählen
PID = 0x06d = PMT
PID = 0x400 = Audio MPEG (typ 0x03)
PID = 0x401 = Stream-type 0x06 PES Packet containing private data
Descriptoren: keine(!)
Das dürften dann DVB-Datenpipes sein, hat weniger Overhead als ein PES und ist mMn besser geeignet für Ancillary Daten.carsten hat geschrieben: ↑Di 13. Jul 2021, 00:30
Da ist was. Man findet es in der PMT von Hitradio FFH. Ich mußte hier auch den ganzen Transponder laden.
Der Stream 0x0401 besteht im wesentlichen aus leeren Frames (viele Frames bestehen nur aus Adaption, ein paar wenige haben ein paar Byte Nutzdaten). Manachmal steht sowas wie "CvRCrB" als Payload drin. Es sieht nicht wie ein PES aus, einfach nur ganz wenige, nackige Daten. Evtl. habe ich nicht lange genug auf ein Frame mit PES Header gewartet.Code: Alles auswählen
PID = 0x06d = PMT PID = 0x400 = Audio MPEG (typ 0x03) PID = 0x401 = Stream-type 0x06 PES Packet containing private data Descriptoren: keine(!)
Das sieht mir irgendwie nicht nach RDS aus, dazu ist es irgendwie zu wenig. Der Wert 0xc3 scheint eine wichtige Rolle zu spielen
Die Menge an möglichen Verfahren zur Übertragung von RDS scheint mir da recht kreativ genutzt zu werden. Das hier wäre jetzt Möglichkeit 4, wenn es sich doch um RDS handelt.
Das macht eine Implementierung immer mehr zu einer ausführlichen Tätigkeit.
Grüße,
Carsten
Der Platz ist sehr wahrscheinlich mit einer harmlosen Maßnahme zu schaffen: Verlagerung der HbbTV-Videotexte von Transponder ins Internet. Also dorthin, wo die anderen HbbTV-Daten sowieso liegen. Der Gag ist, dass der Zustand, der hinsichtlich der von den Transpondern zu entfernenden HbbTV-Daten eintreten würde, schonmal da war, bis 2018. Zu einer Zeit, in der Fernseher noch wesentlich seltener als heute am Internet hingen.RainerZ hat geschrieben: ↑Di 13. Jul 2021, 10:58 Trotzdem, wenn man sieht auf wievielen DVB-S2 fähigen Receivern die Programme nicht laufen, sollte die ARD doch lieber die MP2 Datenrate auf meinetwegen 192 bis 256 kbits reduzieren und die Programme auf den DVB-S2 Fernsehtranspondern verteilt unterbringen...