Sound in FPC/Lazarus generieren

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
oliver2104
Beiträge: 22
Registriert: Sa 26. Dez 2020, 13:22

Sound in FPC/Lazarus generieren

Beitrag von oliver2104 »

Hallo,
ich möchte ein wenig mit der Soundkarte experimentieren.
als einfaches Beispiel würd ich gerne einen 440Hz Sinuston für 1sec ausgeben.
Die Tonfrequenz sollte wirklich zur Laufzeit generiert werden,
also keine Wiedergabe von vorhandenen *.wav, *.mp3 etc.
hat jemand Tips, wie ich das unter Linux angehen kann ?
ev. mit PortAudio ?

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sound in FPC/Lazarus generieren

Beitrag von Winni »

oliver2104 hat geschrieben:
Mo 15. Feb 2021, 11:47
Hallo,
ich möchte ein wenig mit der Soundkarte experimentieren.
als einfaches Beispiel würd ich gerne einen 440Hz Sinuston für 1sec ausgeben.
Die Tonfrequenz sollte wirklich zur Laufzeit generiert werden,
also keine Wiedergabe von vorhandenen *.wav, *.mp3 etc.
hat jemand Tips, wie ich das unter Linux angehen kann ?
ev. mit PortAudio ?

Hi!

Wenn Du english (oder plattdeutsch) kannst, dann guck mal nach Beiträgen von
"Fred vs" im internationalen Forum.

Zusammen mit ihm hab ich hier z.B. bei der Sound-Wellen-Generierung rumgespielt:

https://forum.lazarus.freepascal.org/in ... #msg390913

Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sound in FPC/Lazarus generieren

Beitrag von Winni »

Hallo!

Anbei die Alsa_beep.zip.

Sie enthält

* Die unit alsa_sound lädt die Alsa lib dynamisch (libasound.so.2) und zeigt wie man ein Beep erzeugt. Alles von Fred vS. Ich hab da noch die Wellenformen und ein paar Sounds hinzugefügt.

* Dann gibt's noch eine Demo, mit Mono, Stereo,Sinus, Rechteck und Sägezahn-Wellen, und ein paar Polizei- und Bergbus-Hupen. Alles von mir.

Alles nicht mehr so einach wie zu Turbo-Zeiten....

In case of trouble: Fragen.

Winni
Dateianhänge
Alsa_Beep.zip
(516.15 KiB) 221-mal heruntergeladen
Zuletzt geändert von Winni am Mo 15. Feb 2021, 18:40, insgesamt 1-mal geändert.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Sound in FPC/Lazarus generieren

Beitrag von kupferstecher »

oliver2104 hat geschrieben:
Mo 15. Feb 2021, 11:47
ev. mit PortAudio ?
Ja, PortAudio funktioniert.

Unter LinuxMint hab ich das mal gemacht, PortAudio installieren:
sudo apt-get install portaudio19-dev
Die PortAudio-Pascal-Bindings-Unit (portaudio.pas) ins Projekt einbinden und loslegen:-)

oliver2104
Beiträge: 22
Registriert: Sa 26. Dez 2020, 13:22

Re: Sound in FPC/Lazarus generieren

Beitrag von oliver2104 »

Hallo Winni, Hallo kupferstecher,
hab mir gerade Alsa_Beep.zip heruntergeladen und werd mir auch PortAudio genauer anschauen.
das wird mich vermutlich einige Zeit beschäftigen.
jedenfalls vielen Dank euch Beide
L.G.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Sound in FPC/Lazarus generieren

Beitrag von corpsman »

Servus,

Mein Hörtest Example macht das mit Bass.dll / Bass.so hatte ich auf einem der Letzen Lazarustreffen vorgestellt. Da ist direkt ne Routine drin die verschiedene Frequenzen erzeugen kann (mono und auch stereo). Evtl ist das einfacher für dich ;)
--
Just try it

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sound in FPC/Lazarus generieren

Beitrag von Winni »

Hi!

BASS ist hervorragend, wenn man sich z.B. einen Audio-Player mit Equalizer bauen will.
Und es läuft trotz aller Komplexität einwandfrei unter Linux und Windows.

Aber nur um der Machine ein BEEP zu entlocken??

BASS hat doch eine recht steile Lernkurve und alleine die BASS.chm umfasst 210 Seiten.
Und da steht nicht drinnen, wie man einen Player baut, sondern nur, welche Parameter der Funktion welche Bedeutung und welchen Datentyp besitzen. Da sind noch nicht einmal die Zusatzmodule enthalten, z.B. CD, Flac oder Bass_FX für z.B. Equalizer. Die haben jeweils eigenständige Dokumentationen.

Kurzum: Bass ist eine wirklich vielseitige Audio-Lib - aber um nur ein BEEP zu erzeugen, ist das doch mit Kanonen auf Spatzen geschossen.

Winni

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Sound in FPC/Lazarus generieren

Beitrag von corpsman »

@winni,

ich hab die chm nicht gelesen :shock:

und bei mir sind es nur diese Zeilen:

Code: Alles auswählen


Uses bass;

Var
  PreviewStream: HSTREAM;
  hz: integer = 50;
  t: Integer = 0;
  Shutdown: Boolean = false;

Function GetPreviewData(handle: HSTREAM; buffer: Pointer; length: DWORD; user: Pointer): DWORD;
{$IFDEF MSWINDOWS} stdcall{$ELSE} cdecl{$ENDIF};
Var
  buf: PSingle;
  len, i: Integer;
  v, s: Single;
  w: integer;
Begin
  buf := buffer;
  len := length Div (4 * 2); // 4- Byte Pro Wert * 2 Kanäle
  If hz = 0 Then Begin
    For i := 0 To len - 1 Do Begin
      v := 0;
      // Linker Kanal
      buf^ := V;
      inc(buf);
      // Rechter Kanal
      buf^ := V;
      inc(buf);
      // Wrap Around bei einer Vollen Periode
      t := (t + 1);
      If t >= w Then t := 0;
    End;
  End
  Else Begin
    s := 2 * pi * hz / SampleRate;
    w := (SampleRate Div hz);
    For i := 0 To len - 1 Do Begin
      v := sin(s * t);
      // Linker Kanal
      buf^ := V;
      inc(buf);
      // Rechter Kanal
      buf^ := V;
      inc(buf);
      // Wrap Around bei einer Vollen Periode
      t := (t + 1);
      If t >= w Then t := 0;
    End;
  End;
  result := len * (4 * 2);
End;

Procedure tone(pin: cuint8; frequency: cunsigned; duration: culong);
Var
  t: Int64;
Begin
  If Shutdown Then exit;
  form1.Timer1.Enabled := false;
  hz := frequency;
  BASS_SetVolume(1);
  If duration > 1000 Then Begin
    duration := 1000;
  End;
  If Not BASS_ChannelPlay(PreviewStream, true) Then Begin
    Raise Exception.Create('Could not start stream.');
  End;
  t := GetTickCount64;
  While t + duration >= GetTickCount64 Do Begin
    Application.ProcessMessages;
    If Shutdown Then exit;
  End;
  BASS_ChannelStop(PreviewStream);
  form1.Timer1.Enabled := true;
End;

Procedure HAL_init(); cdecl public name 'HAL_init';
Begin
  PreviewStream := BASS_StreamCreate(SampleRate, 2, BASS_SAMPLE_FLOAT, @GetPreviewData, Nil);
End;

Procedure OS_Down();
Begin
  Shutdown := true;
  BASS_ChannelStop(PreviewStream);
  BASS_StreamFree(PreviewStream);
End;
Wie man sehen kann ist das aus einem Projekt wo FPC einem C-Quellcode vorgauckelt ein Arduino zu sein ;). Das Präsentiere ich auf dem nächsten Lazarus treffen *g*
--
Just try it

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sound in FPC/Lazarus generieren

Beitrag von Winni »

Hi!

Ferrari gekauft und nur den Ersatzreifen benutzt.
Kann man natürlich auch machen.

Für den PC fehlt da allermindestens noch ein

Code: Alles auswählen

Bass_Init;
Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sound in FPC/Lazarus generieren

Beitrag von Winni »

Hi!

Um das ganze etwas zu hübschen, kannst Du die letzte Sekunde bzw.1000 ms damit verbringen, den Ton "abzuwürgen". Hört sich aber bei einem ganzen Song eindrucksvoller an, als bei einem simplen Ton.

Code: Alles auswählen


var killRunning : Boolean = false;

procedure KillEngine(B_Stream: DWord);
begin
   killRunning := true;
    // slide the frequency down
    BASS_ChannelSlideAttribute(B_Stream,BASS_ATTRIB_FREQ,1000,500);
    Sleep(300);
    // and fade-out
    BASS_ChannelSlideAttribute(B_Stream,BASS_ATTRIB_VOL,-1,200);
    // wait for slide to finish
    while (BASS_ChannelIsSliding(B_Stream,0)) do Sleep(1);
end;                               

.....
.....
killrunning := false;
 t := GetTickCount64;
  While t + duration  >= GetTickCount64 Do Begin
    Application.ProcessMessages;
    if  (t+duration -1000 >= GetTIckCount) and (NOT killRunning) then killEngine(PreviwStream);
    If Shutdown Then exit;
  End;

BASS_ChannelStop(PreviewStream);
....
Winni;

oliver2104
Beiträge: 22
Registriert: Sa 26. Dez 2020, 13:22

Re: Sound in FPC/Lazarus generieren

Beitrag von oliver2104 »

Nochmals Danke für die Unit: alsa_sound.pas
Das hat meine ursprüngliche Frage optimal beantwortet.
Insofern wäre das gelöst.
Darf ich noch eine weitere Frage stellen ?
Als zweites Beispiel würd ich gern einen Ton ausgeben solange eine Taste gedrückt gehalten wird.
D.h. der Ton startet mit OnKeyDown und wird bei OnKeyUp beendet.
wäre das mit alsa_sound.pas auch möglich ?

Antworten