[gelöst] Audio abspielen

Für Fragen von Einsteigern und Programmieranfängern...
Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

[gelöst] Audio abspielen

Beitrag von Stefan67 »

Ich möchte Audio-Dateien abspielen und habe mich für uos entschieden. Die Beispieldateien kann ich compilieren und sie funktionieren auch. Aber uos in meinem eigenen Programm einzubinden, gelingt mir einfach nicht. Leider hat uos nur eine sehr knappe Anleitung. Dort steht z.B.:
First: add uos_flat or uos in your uses section. (for uoslib add uoslib_h)
Was dort in der Klammer steht, verstehe ich nicht, aber wenn ich in meinem Programm die "uses-Zeile" entsprechend ergänze
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, uos_flat;
meldet der Compiler einen Fehler:
unit1.pas(8,68) Fatal: Can not find unit uos_flat used by Unit1.
Daraufhin habe ich in der Datei fpc.cfg unter # searchpath for units and other system dependent things versucht den Pfad zu den Dateien von uos einzutragen, leider ohne Erfolg. Nach zwei Tagen des Suchens und Versuchens ohne Erfolg bin ich nun hier gelandet. :wink:

Mein erster Beitrag also, deshalb erst mal ein freundliches Hallo an alle! :D Noch schnell etwas über mich: Früher habe ich viel mit Turbo Pascal gemacht, noch vor OOP. Ja, ja, so alt bin ich schon. :mrgreen: Nach Jahren der Abstinenz habe ich nun wieder Blut geleckt und freue mich, dass Pascal nicht nur überlebt hat, sondern sich sogar noch weiter entwickeln konnte. Ich arbeite unter Linux, möchte aber, dass mein Programm (wenn ich es denn fertig bekomme) auch für Windows kompilierbar ist.
Danke für eure Aufmerksamkeit. Ich freue mich auf eure Hilfe. :)
Zuletzt geändert von Stefan67 am Di 9. Sep 2014, 17:34, insgesamt 1-mal geändert.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2840
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Audio abspielen

Beitrag von m.fuchs »

Stefan67 hat geschrieben:Was dort in der Klammer steht, verstehe ich nicht, aber wenn ich in meinem Programm die "uses-Zeile" entsprechend ergänze
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, uos_flat;
meldet der Compiler einen Fehler:
unit1.pas(8,68) Fatal: Can not find unit uos_flat used by Unit1.
Also scheitert es erstmal am Einbinden? Wo hast du die UOS-Units denn hingelegt? In das gleiche Verzeichnis (oder einen Unterordner) wie dein Programm?
Stefan67 hat geschrieben:Daraufhin habe ich in der Datei fpc.cfg unter # searchpath for units and other system dependent things versucht den Pfad zu den Dateien von uos einzutragen, leider ohne Erfolg. Nach zwei Tagen des Suchens und Versuchens ohne Erfolg bin ich nun hier gelandet. :wink:
Finger weg von der fpc.cfg! Schau mal unter Projekt => Projekteinstellungen => Pfade => Andere Units. Dort kannst du zusätzliche Suchepfade für dein Projekt eintragen. Das ist besser, als irgendwelche globalen Einstellungen anzupassen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
theo
Beiträge: 10955
Registriert: Mo 11. Sep 2006, 19:01

Re: Audio abspielen

Beitrag von theo »

Das Beste wäre wohl ein Lazarus Package zu machen.
http://wiki.freepascal.org/How_To_Write ... mponent/de

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Audio abspielen

Beitrag von Stefan67 »

Ok, danke! Compiler läuft nun durch, aber das Programm meldet:
Semaphore init failed (possibly too many concurrent threads).
Was bedeutet das?

Hier mal mein Listing:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  uos_flat;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  uos_CreatePlayer(0);
  uos_AddIntoDevOut(0);
  uos_AddFromFile(0,'startgong.mp3');
  uos_Play(0);
end;
 
end.                                  
Was mache ich falsch? :?
Zuletzt geändert von Lori am Do 4. Sep 2014, 16:58, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Benutzeravatar
theo
Beiträge: 10955
Registriert: Mo 11. Sep 2006, 19:01

Re: Audio abspielen

Beitrag von theo »

Hatte mir das heute Mittag mal angeschaut.
Schau dir die .lpr Quellen der Beispiele an. Da steht vieles drin wie (aus der Erinnerung)
uses CMem, CThreads etc.
Kopiere das in deine .lpr

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Audio abspielen

Beitrag von Michl »

Habe es mir ebenfalls gerade angeschaut. Dein Bsp. funktioniert bei mir nur, wenn ich zuvor die DLLs lade, ansonsten gibts bei mir ein SIGSEGV! Wenn ich diese aber lade, ist alles gut (die DLLs habe ich mir mal ins Projektverzeichnis kopiert).

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  if uos_LoadLib(Pchar('LibPortaudio-32.dll'), nil, Pchar('LibMpg123-32.dll'), nil) = 0 then
  begin
    uos_CreatePlayer(0);
    uos_AddIntoDevOut(0);
    uos_AddFromFile(0, pchar('1.mp3'));
    uos_Play(0);
  end else
    ShowMessage('Fehler beim Laden!');
end; 

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Audio abspielen

Beitrag von Stefan67 »

Hilft leider nicht.
unit1.pas(39,19) Error: Identifier not found "uos_CreatePlayer"
Ist auch ziemlich unbefriedigend aufs Geratewohl irgendwas einzubinden. Leider finde ich keine brauchbare Dokumentation für uos, der Autor selbst empfiehlt ja, sich einfach die Beispielprogramme anzusehen. So etwas ist aber leider nichts für Anfänger. Geht das nicht auch einfacher unter FP/Lazarus ein paar audio-Dateien abzuspielen?

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Audio abspielen

Beitrag von Stefan67 »

Michl hat geschrieben:... Dein Bsp. funktioniert bei mir nur, wenn ich zuvor die DLLs lade...
Bei mir läuft Linux.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Audio abspielen

Beitrag von Michl »

Stefan67 hat geschrieben:Bei mir läuft Linux.
Ich bin nicht unter Linux unterwegs, aber auch unter Linux wirst Du erst die Bibliotheken laden müssen. Im Bsp. Simple Player sind sie wie folgt angegeben (je nach 32/64bit):

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
var
  ordir: string;
begin
  ordir := application.Location;
...
   {$IFDEF linux}
    {$if defined(cpu64)}
  Edit1.Text := ordir + 'lib/Linux/64bit/LibPortaudio-64.so';
  Edit2.Text := ordir + 'lib/Linux/64bit/LibSndFile-64.so';
  Edit3.Text := ordir + 'lib/Linux/64bit/LibMpg123-64.so';
  Edit5.Text := ordir + 'lib/Linux/64bit/libSoundTouch-64.so';
{$else}
  Edit1.Text := ordir + 'lib/Linux/32bit/LibPortaudio-32.so';
  Edit2.Text := ordir + 'lib/Linux/32bit/LibSndFile-32.so';
  Edit3.Text := ordir + 'lib/Linux/32bit/LibMpg123-32.so';
  Edit5.Text := ordir + 'lib/Linux/32bit/libSoundTouch-32.so';
{$endif}
            {$ENDIF}
...
daher könnte der Code wie folgt funktionieren (besser ist aber die Lösung, alle Zielsysteme zu definieren siehe Bsp. Simple Player):

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  ordir: string;
begin
  ordir := application.Location;                            //Pfad Deiner Anwendung, wenn die Bibliotheken woanders sind, müsste der Pfad angepasst werden
{$if defined(cpu64)}
  if uos_LoadLib(
    Pchar(ordir + 'lib/Linux/64bit/LibPortaudio-64.so'),
    Pchar(ordir + 'lib/Linux/64bit/LibSndFile-64.so'),      //diese Bibliothek und
    Pchar(ordir + 'lib/Linux/64bit/LibMpg123-64.so'),
    Pchar(ordir + 'lib/Linux/64bit/libSoundTouch-64.so')    //diese Bibliothek müssten nicht unbedingt zum mp3 abspielen geladen werden
    ) = 0 then
{$else}
  if uos_LoadLib(
    Pchar(ordir + 'lib/Linux/32bit/LibPortaudio-32.so'),
    Pchar(ordir + 'lib/Linux/32bit/LibSndFile-32.so'),      //diese Bibliothek und
    Pchar(ordir + 'lib/Linux/32bit/LibMpg123-32.so'),
    Pchar(ordir + 'lib/Linux/32bit/libSoundTouch-32.so')    //diese Bibliothek müssten nicht unbedingt zum mp3 abspielen geladen werden
    ) = 0 then
{$endif}
  begin
    uos_CreatePlayer(0);
    uos_AddIntoDevOut(0);
    uos_AddFromFile(0, Pchar('1.mp3'));                     //Pfad Deines abzuspielenden MP3 anpassen
    uos_Play(0);
  end else
    ShowMessage('Fehler beim Laden!');
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Audio abspielen

Beitrag von Michl »

Stefan67 hat geschrieben:Hilft leider nicht.
unit1.pas(39,19) Error: Identifier not found "uos_CreatePlayer"
Dann hast Du unter uses nicht mehr "uos_flat" eingebunden (in Deinem vorherigen geposteten Code war die Unit noch eingebunden).
Stefan67 hat geschrieben:Ist auch ziemlich unbefriedigend aufs Geratewohl irgendwas einzubinden. Leider finde ich keine brauchbare Dokumentation für uos, der Autor selbst empfiehlt ja, sich einfach die Beispielprogramme anzusehen. So etwas ist aber leider nichts für Anfänger. Geht das nicht auch einfacher unter FP/Lazarus ein paar audio-Dateien abzuspielen?
Möglicherweise ist "Bass" einfacher zum Abspielen von MP3 zu nutzen. Dort bindet man nur 1 Bibliothek ein. Siehe http://www.lazarusforum.de/viewtopic.php?p=67783#p67783. Allerdings muss man dort auch wissen, was man tut.

Ich habe nicht alle Möglichkeiten getestet, die im Wiki http://wiki.lazarus.freepascal.org/Audio_libraries/de verlinkt sind. Evtl. ist dort noch eine einfacherere Variante?! IMHO wirst Du aber nicht umhin kommen eine Bibliothek einzubindnen, um ein MP3 unter Linux abzuspielen (unter Windows könnten WAVs mit PlaySound abgespielt werden).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Audio abspielen

Beitrag von Stefan67 »

Danke, Michl.
Dein Beispiel funktioniert leider nicht, compilieren geht, aber dann kommt deine Fehlermeldung.

Und folgender code bricht wieder mit der Fehlermeldung "Semaphore init failed (possibly too many concurrent threads)." ab:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, uos_flat;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
    uos_LoadLib('lib/Linux/32bit/LibPortaudio-32.so', 'lib/Linux/32bit/LibSndFile-32.so', 'lib/Linux/32bit/LibMpg123-32.so', 'lib/Linux/32bit/libSoundTouch-32.so');
 
    uos_CreatePlayer(0);
    uos_AddIntoDevOut(0);
    uos_AddFromFile(0, Pchar('gong.mp3'));
    uos_Play(0);
 
end;
 
end.
 
Im wiki steht:
For uoslib:

uos_LoadLibs(uoslibFilename, PortAudioFileName, SndFileFileName, Mpg123FileName, SoundTouchFileName); /// full path of libraries
Welche Datei ist mit uoslibFilename gemeint?
Zuletzt geändert von Lori am Do 4. Sep 2014, 16:59, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Audio abspielen

Beitrag von Michl »

K.A. den Bezeichner "uos_LoadLibs" habe ich nicht gefunden (selbst mit einer externen Suche nach dem String in UOS, ist evtl. ein alter/ungültiger Eintrag).

Funktioniert denn das einfache beigefügte Bsp. "consoleplay" bei Dir?!
Stefan67 hat geschrieben:... aber dann kommt eine Fehlermeldung ... "Semaphore init failed (possibly too many concurrent threads)."
Hast Du mal versucht zu debuggen, wo genau die Fehlermeldung kommt?! Ich musste gestern auch etwas "schummeln", da bei der Initialisierung " DefDevIn := Pa_GetDefaultInputDevice();" DefDevIn "Nil" zurückgegeben wurde und es daraufhin zu einer Exception kam.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
theo
Beiträge: 10955
Registriert: Mo 11. Sep 2006, 19:01

Re: Audio abspielen

Beitrag von theo »

Stefan67 hat geschrieben: Und folgender code bricht wieder mit der Fehlermeldung "Semaphore init failed (possibly too many concurrent threads)." ab:
Hast du das, was ich dir hier gesagt habe denn gemacht?
Das sage ich ja nicht nur aus Spaß.

Code: Alles auswählen

 {$DEFINE UseCThreads}
 
uses
  cmem, {$IFDEF UNIX} {$IFDEF UseCThreads}
  cthreads,
  cwstring, {$ENDIF} {$ENDIF}
  Interfaces, // this includes the LCL widgetset
 .....
 

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Audio abspielen

Beitrag von pluto »

Versuch doch mal das mplayer-control(weiß jetzt nicht ob der Name richtig geschrieben ist).
Aber das ist deutlich einfacherer. Ich habe auch schon die VLC-Lib zum laufen gebracht unter Linux.
Ist aber alles andere als Einfach. Kann dir aber gerne dazu ein Beispiel erstellen.
MFG
Michael Springwald

Stefan67
Beiträge: 33
Registriert: Di 2. Sep 2014, 23:49
OS, Lazarus, FPC: Linux 3.16, Lazarus 1.0.14, FPC 2.6.2
CPU-Target: 32Bit

Re: Audio abspielen

Beitrag von Stefan67 »

Das Beispiel consoleplay erzeugt ein leeres Formular, aber keinen Ton.

Folgendes Listing durchläuft auch den Compiler ohne Fehlermeldung, aber ebenfalls kein Ton:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  cmem, {$IFDEF UNIX} {$IFDEF UseCThreads}
  cthreads,
  cwstring, {$ENDIF} {$ENDIF}
  Interfaces, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, uos_flat;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
    uos_LoadLib('lib/Linux/32bit/LibPortaudio-32.so', 'lib/Linux/32bit/LibSndFile-32.so', 'lib/Linux/32bit/LibMpg123-32.so', 'lib/Linux/32bit/libSoundTouch-32.so');
 
    uos_CreatePlayer(0);
    uos_AddIntoDevOut(0);
    uos_AddFromFile(0, Pchar('startgong.mp3'));
    uos_Play(0);
 
end;
 
end.
Während das Beispielprogramm MorseTL einwandfrei funktioniert. :?

@pluto
Ich werde ggf. noch anderes ausprobieren, aber ich will jetzt noch nicht aufgeben.
Zuletzt geändert von Lori am Fr 5. Sep 2014, 19:36, insgesamt 1-mal geändert.
Grund: Bitte den richtigen Highlighter verwenden.

Antworten