Folgende Warnungen sind aufgetreten:
Warning [2] Undefined variable $unreadreports - Line: 34 - File: global.php(961) : eval()'d code PHP 8.2.24 (Linux)
File Line Function
/inc/class_error.php 153 errorHandler->error
/global.php(961) : eval()'d code 34 errorHandler->error_callback
/global.php 961 eval
/showthread.php 28 require_once
Warning [2] Undefined property: MyLanguage::$thread_modes - Line: 43 - File: showthread.php(1621) : eval()'d code PHP 8.2.24 (Linux)
File Line Function
/inc/class_error.php 153 errorHandler->error
/showthread.php(1621) : eval()'d code 43 errorHandler->error_callback
/showthread.php 1621 eval




Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
DAB+ Usb-Stick
#31
(13.07.2018, 06:12)Der kleine Punky schrieb: @sundtek
Hätte auch Interesse am Stick. Aber ich benutze keine Kodi sondern C++ vielleicht hilft das.

Die Tuner sind ja eh bestellbar, Versand ist ab Anfang nächster Woche.

net_open -> open
net_close -> close
net_ioctl -> ioctl

Sicherer ist aber net_* und dann gegen /opt/bin/libmcsimple.so zu linken, dann funktioniert der Code auch unter MacOSX oder über JNI unter Android (oder sobald unser Windows Compatibility Layer mal freigegeben wird auch unter Windows).

DAB Client code:

Parameter:
device ... Gerätepfad
devfd ... Filehandle vom Tuner
running ... sollte -1 sein


Code:
int media_scan_dabfrequencies(char *device, int devfd, int console, int running) {
        int fd;
        int nlen;
        char tmp[30];
        if (devfd>=0)
                fd = devfd;
        else
                fd = net_open(device, O_RDWR);

        if (fd>=0) {
                struct dab_frequency dabf;
                struct dab_tuner dabt;
                int i;
                int e;
                int current_scan_index=-1;
                struct dab_scan_setup setup;
                struct dab_scan_parameters parameters;
                memset(&parameters, 0x0, sizeof(struct dab_scan_parameters));
                memset(&setup, 0x0, sizeof(struct dab_scan_setup));
                net_ioctl(fd, DAB_SCAN_SETUP, &setup);

                do {
                        net_ioctl(fd, DAB_SCAN_NEXT_FREQUENCY, &parameters);
                        if (current_scan_index != parameters.scan_index) {
                                if (console>=0) {
                                        sprintf(tmp, "%s %d\n", dab_frequency_list[parameters.scan_index].channel, dab_frequency_list[parameters.scan_index].freq*1000);
                                        write(console, tmp, nlen);
                                } else {
                                        fprintf(stdout, "%s %d\n", dab_frequency_list[parameters.scan_index].channel, dab_frequency_list[parameters.scan_index].freq*1000);
                                        fflush(stdout);
                                }
                        }

                        switch(parameters.status) {
                        case DAB_SCAN_LOCKED:
                        {
                                if (console>=0) {
                                        write(console, "[LOCKED]\n", 9);
                                } else {
                                        fprintf(stdout, "[LOCKED]\n");
                                }
                                break;
                        }
                        case DAB_SCAN_SEARCHING:
                                usleep(10000);
                                break;
                        case DAB_SCAN_COMPLETE:
                        {
                                if (console>=0) {
                                        write(console, "[FINISHED]\n", 11);
                                } else {
                                        fprintf(stdout, "\nScan completed\n");
                                }
                                break;
                        }
                        }
                        current_scan_index = parameters.scan_index;
                        if (console>=0 && running == 0)
                                break;
                } while (parameters.status != DAB_SCAN_COMPLETE);

                if (devfd == -1)
                        net_close(fd);
        }
        return 0;
}


Scanne DAB Services (gibt SID Und Component ID zurück):
Code:
int media_scan_dabservices(char *device) {
        int fd;
        int rv;
        int i=0;
        fd = net_open(device, O_RDWR);
        if (fd>=0) {
                struct dab_service service;
                printf("Service Name, Service ID, Component ID\n");
                while(1) {
                        service.id=i++;
                        rv = net_ioctl(fd, DAB_GET_SERVICE, &service);
                        if (rv == -1)
                                break;
                        printf("%16s\t0x%x\t0x%x\n", service.service_name, service.sid, service.comp[0]);
                }
                net_close(fd);
        }
        return 0;
}


Sender konfigurieren:

Code:
int set_dab_channel(int fd, uint32_t frequency, uint32_t sid, uint8_t sid_set, uint32_t comp, uint8_t comp_set) {
        struct dab_frequency dabf;
        memset(&dabf, 0x0, sizeof(struct dab_frequency));
        if (sid_set && comp_set)
                printf("Tuning: %d, 0x%x, 0x%x\n", frequency, sid, comp);
        else if (sid_set)
                printf("Tuning: %d, 0x%x\n", frequency, sid);
        else
                printf("Tuning: %d\n", frequency);

        dabf.frequency = frequency;
        if (sid_set) {
                dabf.sid_set = 1;
                dabf.sid = sid;
        }
        if (comp_set) {
                dabf.comp = comp;
                dabf.comp_set = 1;
        }
        net_ioctl(fd, DAB_SET_FREQUENCY, &dabf);
        return 0;
}
Code:
int get_dab_lock(int fd) {
        int i=5;
        struct dab_tuner dabt;
        memset(&dabt, 0x0, sizeof(struct dab_tuner));
        for (i=0;i<10;i++) {
                net_ioctl(fd, DAB_GET_TUNER, &dabt);
                if (dabt.status & DAB_HAS_LOCK) {
                        printf("[LOCKED]");
                        break;
                } else {
                        printf(".");
                }
                usleep(10000);
        }
        printf("\n");
        return 0;
}


Folgende Funktion startet das Playback von Audio direkt im Treiber.
fd sollte der Filehandle zu /dev/dab0 sein (oder /dev/dabX bei mehreren Empfängern).


Code:
int set_mute(int fd, char *arg) {
        int type = 0;
        struct v4l2_control control;
        if (strcmp(arg, "off") == 0) {
                control.id = V4L2_CID_AUDIO_MUTE;
                control.value = 0;
                fprintf(stdout, "Enabling audiostream\n");
                net_ioctl(fd, VIDIOC_S_CTRL, &control);
        } else if (strcmp(arg, "on") == 0) {
                fprintf(stdout, "Disabling audiostream\n");
                control.id = V4L2_CID_AUDIO_MUTE;
                control.value = 1;
                net_ioctl(fd, VIDIOC_S_CTRL, &control);
        } else
                fprintf(stdout, "Wrong argument [%s] choose between on|off\n", arg);

        return 0;
}


Die PCM Samples kann man mittels read() von /dev/dab0 auslesen, by default Spielt ja der Treiber Audio ab, dieses Verhalten kann man auch ausschalten.
Eine Besonderheit hier ist dass die PCM Samples auch WAV Header beinhalten, wer keine WAV Header benötigt sollte die Samples von /dev/dsp0 auslesen.

Das war jetzt nur mal der DAB Bereich, FM Radio kann über /dev/radio0 ausgelesen und konfiguriert werden, wir halten uns hierbei an den offiziellen Video4Linux Standard.
Die DAB Schnittstelle ist eine Eigenentwicklung da Linux dafür keine offiziellen Schnittstellen hat.

Wer sich etwas mit der FM Radio Video4Linux API auskennt wird hier Ähnlichkeiten sehen. Die Befehle sind in /opt/include/mediacmds.h definiert.

Einfacher geht's über unseren Streamingserver "rtspd"

/opt/bin/mediaclient --installstreamer

dann im Web http://localhost:22000 die DAB Frequenzen scannen / Playlisten konfigurieren - und via HTTP streamen.
Das ist dann komplett unabhängig von jeder Spezial-API.
Zitieren
#32
kann man die libmcsimple.so auf dem rasp in python importieren?
oder muss man das erst auf dem rasp compilieren?
Zitieren
#33
Wäre auch möglich.
Binaries sind für so gut wie alle bekannten Systeme verfügbar.
Zitieren
#34
Hey ich habe mir jetzt den kompletten Tread druchgelesen, jedoch verstehe ich euch nicht ganz.

Ist jetzt DAB+ mit den Car Pc möglich? Und falls es möglich ist, kann mir vielleicht jemand ne step by step Anleitung für Dummies wie mich reinmachen ?

Was und wo muss ich die Hardware kaufen, gibt es etwas zu beachten ?
Zitieren
#35
Soweit sind wir noch nicht. Es gibt noch keine Software oder plugins. Ausserdem scheint der besagte stick nicht lieferbar zu sein.
Auf meinen warte ich sicher schon 6 Wochen.
Zitieren
#36
Hoffentlich nicht mit Vorkasse... ?
Zitieren
#37
Naja Vorkasse schon aber wenigstens mit PayPal. 2 Wochen geb ich dem Teil noch.....
Was aber echt schade wäre. In diesem stick hätte ich echtes Potential gesehen.
Zitieren
#38
Ich wollte den auch bestellen, aber die Webseite ist schon seit über einem Monat nicht erreichbar. Sehr vertrauenswürdig das ganze, warum der Entwickler da nicht einfach selbst ein paar importiert und in D direkt verkauft ist mir da echt ein Rätsel.
Zitieren
#39
Danke, wollte schon bestellen. Da ich es so verstanden hatte Sad

Irgendwie scheint ja das DAB+ Ding ein ordentliches Problem zu sein..., schade da der Car PC an sich ne hübsche Geschichte ist, vor allem für ältere Fahrzeuge.
Zitieren
#40
Ja da gebe ich dir vollkommen recht! Wie ich schon sagte der Stick hört sich für einen Pi echt interessant an und die Soundausgabe wäre einfach ideal am Raspicar.
Auch über den Support kann man sich nicht wirklich beschweren, aber der Rest macht keinen guten Eindruck. Sad
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 2 Gast/Gäste
RasPiCarProjekt