-
Was ???
findet nicht in /lib/ ???
gottverdammt nochmal, was ist Linux doch ein total beschissenes Betriebssystem!
- - - Aktualisiert - - -
ja, jetzt lässt es sich kompilieren, aber exit mit code 127.
Wie bringt man jetzt das Programm dazu, einen wav file abzuspielen?
- - - Aktualisiert - - -
also, ich gebs auf, diese tinyalsa ist einfach ein völlig unbrauchbares Programm.
Jetzt krieg ich mit den neuen -l -I -L Parametern noch nichtmal mehr meine alten programme compiliert.
So eine Kacke!
Gibt es andere, einfache C/C++ API libs, um wav files abzuspielen, ohne solchen beknackten compile- und link- Einstellungen wie bei tinyalsa?
es muss doch verdammt nochmal ein einfaches #include <XXX.h> ausreichen, verdammt!!
-
unterm Strich muss es eine C/C++ API geben, die zum wav-Abspielen per C Programmierung nicht viel mehr braucht als simple 3 Befehle:
Code:
fp=fopen("wavfile.wav", "r");
playwavfile(fp);
close(fp);
Alles andere muss eine interne Angelegenheit der API lib sein, mit der man als Programmier-End-User nichts zu tun haben muss.
-
also ich muss hier jetzt mal Linux verteidigen .. und das als alteingesessener Windows Nutzer
Linux hat sehr wohl eine brauchbare Nutzer/Gruppen/Gast Rechteverwaltung, man muss nur mal ein wenig Hirnschmalz einsetzen um von den ewig parallelen Zugriffsrechten runterzukommen ...
[SPOILER]einige Ordner auf meiner Festplatte haben 8 Benutzer(-gruppen) ... 0 Übersicht! In Linux lege ich einen Nutzer für NEtzwerkkram an, einen für Datenbank und einen für Webseiten Zeug. Jeder bekommt seine Ordner und für die Libs und Shared Elemente verwende ich dann einfach eine gemeinsame Gruppe mit einem dedizierten Ordner ... so habe ich maximale Sicherheit[/SPOILER]
außerdem ist Linux weit flexibler als Windows und unter der Aufwand eines initialen (aber spürbaren) Lernaufwandes sehr produktiv einsetzbar ... der rest erklärt sich i.d.R. mit ein wenig Google für die notwendigen Komponenten, etwas "man someLib" (wenn man es per apt-get installiert hat) und der Rest ist enthusiasmus ... der RPI ist definitv nichts für mal eben schnell und sauber, sondern für absolute bastler und perfektionisten!
-
ja, für spezielle Zwecke mag das ja sein, aber es fehlt an der Möglichkeit, die Userrechte auf Wunsch auch zu vereinfachen. Dass ich als alleiniger Nutzer nicht festlegen kann, dass ich auch als "pi" immer root Rechte habe, und dann möglicherweise andere Dinge nicht mehr laufen, die nicht für root erlaubt sind, ist einfach ein Unding. Wie auch peterfido schon schrieb, das könnte man auch anders lösen, u.a. als embedded Linux oder wie auch immer. Wer viele User braucht, soll sie haben, aber dass ich meine eigenen wiringPi Programme nicht als pi starten kann vom File Manager aus, ist ein Unding, und dass ich keine Lib-Dateien verschieben kann in ein Systemverzeichnis (z.B. /lib/), ebenfalls, und dass ich ständig sudo nano brauche, um /boot/config.txt zu editieren, ebenfalls, weil es der Editor Leafpad mangels Berechtigung nicht zulässt.
Die ganze GUI ist vollkommener Quatsch, wenn man wegen jedem Mist wieder auf das terminal und die Kommandozeile zurückgeworfen wird, wie vor hundert Jahren. Wozu hat man ne GUI, wenn ständig LeafPad und FileManger ihren Dienst versagen mangels "User-Rechten" ?
Aber hier geht es in dem Topic ja um wav Dateien, und wie man sie mit einer C API einfach programmieren kann, ohne tonnenweise Code selber schreiben zu müssen. Eher so wie oben im Beispiel:
fp=fopen("wavfile.wav", "r");
playwavfile(fp);
close(fp);
Die API Lib kann selbstständig die Metadaten für die Wiedergabe im File lesen und ihn dann entsprechend abspielen, da muss ich mich doch nicht jedesmal haarklein selber drum kümmern müssen!
Das hat ja auch nichts mit Linux direkt zu tun, sondern nur mit den zur Verfügung stehenden C/C++ API libs, und so was muss es jetzt einfach mal schon geben, in den 40 Jahren seit K+R.
Allerdings hat es was mit der Raspi org zu tun, dass die nämlich endlich mal nicht nur Python, sondern auch C/C++ anständig supporten.
Es gibt ja noch nicht mal für die meisten HATs auch C/C++ Treiber- libs, sondern nur für Python
-
es klappt immer noch nicht.
Wo gibt es denn jetzt ein funktionierenden Code, mit dem man per tinyalsa oder was auch immer einen wav sound einfach mal eben aus einem C programm heraus abspielen kann?? :confused:
-
ob es noch jemand gibt, der einfache Kommandos aus "echten originären, portierbaren" C API libs kennt oder einen Wrapper um tinyalsa Codes selber erstellen kann, damit einfaches wav abspielen mit automatischer Parametererkennung mit 1 einfachen Befehl möglich ist?
-
leider kann ich das Programm bei mir nicht zum Laufen kriegen, um einen wav file abzuspielen...
:(
ich finde aber auch die Doku (wie auch schon hirnfrei bemerkte) zu unklar.
:(
neuer Ansatz:
hirnfreis Code:
Code:
#include <alsa/asoundlib.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
typedef struct _FILE_head
{
unsigned char ID[4];
unsigned int Length;
unsigned char Type[4];
} FILE_head;
typedef struct _FORMAT
{
short wFormatTag;
unsigned short wChannels;
unsigned int dwSamplesPerSec;
unsigned int dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short wBitsPerSample;
} FORMAT;
typedef struct _CHUNK_head
{
unsigned char ID[4];
unsigned int Length;
} CHUNK_head;
snd_pcm_t *soundKarte;
bool Init(const char *name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
{
int err;
snd_pcm_format_t bits;
unsigned int resample = 1;
switch(WaveBits)
{
case 8:
bits = SND_PCM_FORMAT_U8;
break;
case 16:
bits = SND_PCM_FORMAT_S16;
break;
case 24:
bits = SND_PCM_FORMAT_S24;
break;
case 32:
bits = SND_PCM_FORMAT_S32;
break;
}
snd_pcm_hw_params_t *hw_params;
if(name == NULL)
{
err = snd_pcm_open(&soundKarte, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0);
}
else
{
err = snd_pcm_open (&soundKarte, name, SND_PCM_STREAM_PLAYBACK, 0);
}
if(err < 0)
{
cout << "Init: Kann die Soundkarte nicht öffnen! " << name << " (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
{
cout << "Init: Parameter können nicht initialisiert werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_any(soundKarte, hw_params)) < 0)
{
cout << "Init: Parameter können nicht ermittelt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
err = snd_pcm_hw_params_set_rate_resample(soundKarte, hw_params, resample);
if(err < 0)
{
cout << "Init: Resampling kann nicht eingeschaltet werden " << snd_strerror(err) << endl;
return err;
}
if((err = snd_pcm_hw_params_set_access(soundKarte, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
{
cout << "Init: Zugriffstyp kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_format(soundKarte, hw_params, bits)) < 0)
{
cout << "Init: Sample-Format kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_channels(soundKarte, hw_params, channels)) < 0)
{
cout << "Init: Anzahl der Kanäle kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params_set_rate_near(soundKarte, hw_params, &actualRate, 0)) < 0)
{
cout << "Init: Sample-Rate kann nicht auf " << actualRate << " gesetzt werden (" << snd_strerror (err) << ")" << endl;
return false;
}
if((err = snd_pcm_hw_params (soundKarte, hw_params)) < 0)
{
cout << "Init: Üarameters können nicht gesetzt werden(" << snd_strerror (err) << ")" << endl;
return false;
}
// snd_pcm_hw_params_get_buffer_size(hw_params, &bufferSize);
snd_pcm_hw_params_free(hw_params);
if((err = snd_pcm_prepare(soundKarte)) < 0)
{
cout << "Init: Audio kann nicht zur Nutzung vorbereitet werden (" << snd_strerror (err) << ")" << endl;
return false;
}
return true;
}
bool UnInit()
{
snd_pcm_close(soundKarte);
return true;
}
int main()
{
FORMAT format;
FILE_head head;
CHUNK_head chead;
char *wave;
register snd_pcm_uframes_t count, frames;
int datei;
unsigned int WaveSize;
datei = open("/home/pi/Music/cantalow.wav", 00);
read(datei, &head, sizeof(FILE_head));
read(datei, &chead, sizeof(CHUNK_head));
read(datei, &format, sizeof(FORMAT));
wave = (char *) malloc(head.Length);
read(datei, wave, head.Length);
WaveSize = head.Length * 8 / ((unsigned int)format.wBitsPerSample * (unsigned int)format.wChannels);
close(datei);
Init("plughw:1,0", format.wChannels, format.dwSamplesPerSec, format.wBitsPerSample);
count = 0;
do
{
frames = snd_pcm_writei(soundKarte, wave + count, WaveSize - count);
if (frames < 0) frames = snd_pcm_recover(soundKarte, frames, 0);
if (frames < 0)
{
printf("Kann wav nicht abspielen: %s\n", snd_strerror(frames));
break;
}
count += frames;
} while (count < WaveSize);
if (count == WaveSize) snd_pcm_drain(soundKarte);
free(wave);
UnInit();
return 0;
}
Ich selber muss hier aber wieder komplett passen, ich verstehe absolut nichts mehr von dem, was da passiert, noch nicht mal wie und wo in main() jetzt überhaupt etwas in der Art steht wie
playwavfile(filename)
ob man das irgendwie in einen verständlichen wrapper rein kriegt?
:confused:
-
Machen wir nen Deal.
Du hilfst mir die globale Variable los zu werden und ich bau dir daraus ein
Code:
playwave(file, soundkarte);
Weil ich kämpfe heute schon den ganzen Tag daran anstatt eine globale Variable eine übergebne Variable zu basteln und ich kriege es nicht gebacken. Wie so ein kleine Noob :(
-
meinst du
snd_pcm_t *soundKarte
?
das ist wschl Teil des Problems, eventuell wäre es das beste, ein Objekt daraus zu machen mit den Methoden
init()
open()
close()
play()
record()
ich würde sie ansonsten in einer Funktion
Code:
snd_pcm_t * init_soundKarte(soundKarte){
snd_pcm_t * retstruc = soundKarte;
//...
//...
return retstruc;
}
eingangs lokal mit Werten initialisieren, dann kannst du sie als Struktur an andere Funktionen über den Pointer weiterreichen.
Der allererste Aufruf müsste dann in main() erfolgen.
In main() müsste dazu nur stellvertretend eine lokale Variable
snd_pcm_t * soundKarte;
angelegt werden.
Dann wird hier per
init_soundKarte(soundKarte);
die Struktur "gefüllt",
und dann kann sie im Rest des Programms entsprechend weiter gereicht und benutzt werden, und so hat man sie per Parameter dort zur Verfügung.
z.B. auch in
Code:
bool UnInit(soundKarte)
{
snd_pcm_close(soundKarte);
return true;
}
und entsprechend an allen anderen Funktionen, wie z.B. auch als weiterer Parameter in Init().
Meintest du es so in etwa?
ps,
Ich sehe allerdings in deinem Code auch gar nicht die Stelle, wo soundKarte überhaupt erstmalig mit Werten "gefüllt" wird... :-/
-
Code:
if(name == NULL)
{
err = snd_pcm_open(&soundKarte, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0);
}
Hier wird die Soundkarte geöffnet und der Handler soundKarte initialisiert. Von da an geht es ja nur noch darum den Funktionen zu sagen mit welchem Handler sie zu arbeiten hat.
Ich hab auch glaub ich eine gute Lösung. Funktioniert zwar noch nicht, aber ich denke morgen knack ich das. Dann schau ich nach deiner Funktion ^^
PS:
Wenn ich mir meine Threads so ansehe, wie zwei scheinen uns gut zu verstehen ^^