Recent

Author Topic: alsa beep - linux only  (Read 3873 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #15 on: October 25, 2020, 02:03:47 pm »
This tested on Debian 10.1 64 bit on i5, it is very not loud even not louder than silence.

 ;)

That's actually more helpful than the twit on StackOverflow who insisted that a mainboard beeper was always redirected to ALSA so \a would work in all cases. And then got stroppy.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #16 on: October 25, 2020, 02:16:20 pm »
Quote
That's actually more helpful than the twit on StackOverflow who insisted that a mainboard beeper was always redirected to ALSA so \a would work in all cases...

Huh, I did not follow that battle but this make me think to something.

I will check my bios and I think that the system-beep was set as disabled.

I will enable it and maybe continue the battle.

Write you later.
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #17 on: October 25, 2020, 02:31:19 pm »
Quote
Write you later

Ok, system beep enabled in bios.

But even with this, on Debian 10.1, 64 bit, on i5 from a ThinkPad X390, I can only ear the click of the button or the clack of the key pressed but nothing else.

This using XkbForceBell or XBell.



I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #18 on: October 25, 2020, 02:42:42 pm »
Does  xkbbell  work?

If I continue the discussion anywhere it's likely to be the XDG mailing list, since I'd expect there to be people there from the major desktops and distreaux.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #19 on: October 25, 2020, 02:46:42 pm »
Quote
Does  xkbbell  work?

Do you mean the executable?

This works here in perfect silence:

Code: Pascal  [Select][+][-]
  1. $ xkbbell

Code: Pascal  [Select][+][-]
  1.  $ xkbbell -version
  2.     xkbbell (xkbutils) 1.0.4

Same silence with this:

Code: Pascal  [Select][+][-]
  1. $  xkbbell -force

« Last Edit: October 25, 2020, 02:51:34 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #20 on: October 25, 2020, 02:51:02 pm »
If you run on the system console (via <Ctrl><Alt><F1> etc.) does  echo -ne '\a'  beep?

If it doesn't, it's a kernel/hardware issue. If it does, it's a desktop/X11 issue.

MarkMLl

ps If you're not used to that, it's usually <Ctrl><Alt><F1> to get back to your desktop.
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #21 on: October 25, 2020, 03:05:24 pm »
If you run on the system console (via <Ctrl><Alt><F1> etc.) does  echo -ne '\a'  beep?

It does the same noise: silent.

Quote
If it doesn't, it's a kernel/hardware issue.

Hum, yes maybe, but when some applications are not happy, like xfce4-terminal, it can produce a beep.

Anyway, XkbForceBell or XBell will not be available with Wayland.
« Last Edit: October 25, 2020, 03:21:26 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #22 on: October 25, 2020, 03:09:26 pm »
If you run on the system console (via <Ctrl><Alt><F1> etc.) does  echo -ne '\a'  beep?

It does the same noise: silent.

Quote
If it doesn't, it's a kernel/hardware issue.

Hum, yes maybe, but when some applications are not happy, like xfce4-terminal, it can produce a beep.

Which I suspect you will find is via libnotify and ALSA, and I suspect that in that particular case the shell will also respond to \a

What I've not found out is how to duplicate that behaviour from an app, and that's an XDG question.

Quote
Anyway, XkbForceBell or XBell be will not be available with Wayland.

True, although I think that that's on their list of things that must be reinstated in the medium term.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #23 on: October 25, 2020, 04:53:49 pm »
Quote
Which I suspect you will find is via libnotify and ALSA, and I suspect that in that particular case the shell will also respond to \a

Here it seems that it was a problem with PulseAudio.
By default, audible-bell (beep redirection) is not set, this must be added at end of /etc/pulse/default.pa:

Code: Pascal  [Select][+][-]
  1. # audible bell
  2. load-sample-lazy x11-bell /usr/share/sounds/freedesktop/stereo/bell.oga
  3. load-module module-x11-bell sample=x11-bell

Also to enable beep and echo -e '\a' in terminal, you need in ~/.config/xfce4/terminal/terminalrc to enable MiscBell to true.

Now indeed, beep, echo -e '\a', xkbbell work on terminal.

And... with fpc, xbell works too (but no success with XkbForceBell).

All that said that I am not sure that using XkbForceBell or xbell will be out-of-the-box for everybody.


« Last Edit: October 25, 2020, 04:59:24 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #24 on: October 25, 2020, 05:58:04 pm »
Quote
Which I suspect you will find is via libnotify and ALSA, and I suspect that in that particular case the shell will also respond to \a

Here it seems that it was a problem with PulseAudio.
By default, audible-bell (beep redirection) is not set, this must be added at end of /etc/pulse/default.pa:

Code: Pascal  [Select][+][-]
  1. # audible bell
  2. load-sample-lazy x11-bell /usr/share/sounds/freedesktop/stereo/bell.oga
  3. load-module module-x11-bell sample=x11-bell

Confirmed that that's not set for Debian "Buster" with KDE. But XkbForceBell() still works :-/

Quote
Also to enable beep and echo -e '\a' in terminal, you need in ~/.config/xfce4/terminal/terminalrc to enable MiscBell to true.

Now indeed, beep, echo -e '\a', xkbbell work on terminal.

And... with fpc, xbell works too (but no success with XkbForceBell).

All that said that I am not sure that using XkbForceBell or xbell will be out-of-the-box for everybody.

Definitely too much hassle for most. I mean, I pride myself on being a fairly high-end nerd but all this grief with BIOS settings, files in /etc. possibly a notification daemon, desktop/wm configuration in different places... it's really no joke.

MarkML
« Last Edit: October 25, 2020, 06:00:15 pm by MarkMLl »
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #25 on: October 25, 2020, 06:43:11 pm »
Quote
Definitely too much hassle for most. I mean, I pride myself on being a fairly high-end nerd but all this grief with BIOS settings, files in /etc. possibly a notification daemon, desktop/wm configuration in different places... it's really no joke.

Yes, I fear that the solution of Robert Rozee is the best.
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #26 on: October 25, 2020, 07:16:32 pm »
Quote
But XkbForceBell() still works :-/

Hum, strange, here it does not work.

I noted too that on terminal:

Code: Pascal  [Select][+][-]
  1. $ xkbbell

produce sound but this:

Code: Pascal  [Select][+][-]
  1. $ xkbbell -force

Gives silent.

May I ask if Xbell() is working for you in pascal?

Code: Pascal  [Select][+][-]
  1. program gui_beep;
  2.  
  3. uses
  4. xlib;
  5.  
  6. var
  7.   dpy: PDisplay;
  8. begin
  9.  dpy := XOpenDisplay(nil);
  10.  XSynchronize(dpy, 1);
  11.  xbell(dpy,0);
  12.  xflush(dpy);
  13.  XCloseDisplay(dpy);
  14. end.
  15.  

Thanks.

(Here it works)

Fre;D
« Last Edit: October 25, 2020, 08:00:37 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 1447
Re: alsa beep - linux only
« Reply #27 on: October 25, 2020, 09:44:14 pm »
The code I posted earlier https://forum.lazarus.freepascal.org/index.php/topic,49502.msg381874.html#msg381874 is running in production.

xkbbell is working both with and without -force... make sure you're not doing something like trying to sudo it.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Fred vS

  • Hero Member
  • *****
  • Posts: 1982
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #28 on: October 25, 2020, 10:56:48 pm »
The code I posted earlier https://forum.lazarus.freepascal.org/index.php/topic,49502.msg381874.html#msg381874 is running in production.

xkbbell is working both with and without -force... make sure you're not doing something like trying to sudo it.

No, sudo was not used.

Anyway, I did adapt Robert Rozee code to laod dynamically libasound.so.2 and merge it as unit:
Code: Pascal  [Select][+][-]
  1.  // Original beeper.inc of
  2.  // Robert Rozee, 30-April-2020
  3.  // rozee@mail.com
  4.  
  5.  // Dynamic loading
  6.  // FredvS fiens@hotmail.com
  7.  
  8.  
  9. unit alsa_beep;
  10.  
  11. {$mode objfpc}{$H+}
  12. {$PACKRECORDS C}
  13.  
  14. interface
  15.  
  16. uses
  17.   dynlibs,
  18.   CTypes,
  19.   Math;
  20.  
  21. type
  22.   { Signed frames quantity }
  23.   snd_pcm_sframes_t = cint;
  24.  
  25.   { PCM handle }
  26.   PPsnd_pcm_t = ^Psnd_pcm_t;
  27.   Psnd_pcm_t  = Pointer;
  28.  
  29.   { PCM stream (direction) }
  30.   snd_pcm_stream_t = cint;
  31.  
  32.   { PCM sample format }
  33.   snd_pcm_format_t = cint;
  34.  
  35.   { PCM access type }
  36.   snd_pcm_access_t = cint;
  37.  
  38.   { Unsigned frames quantity }
  39.   snd_pcm_uframes_t = cuint;
  40.  
  41. const
  42.   { Playback stream }
  43.   SND_PCM_STREAM_PLAYBACK: snd_pcm_stream_t = 0;
  44.  
  45.   { Unsigned 8 bit }
  46.   SND_PCM_FORMAT_U8: snd_pcm_format_t       = 1;
  47.  
  48.   { snd_pcm_readi/snd_pcm_writei access }
  49.   SND_PCM_ACCESS_RW_INTERLEAVED: snd_pcm_access_t = 3;
  50.  
  51.   // Dynamic load : Vars that will hold our dynamically loaded functions...
  52.   // *************************** Alsa Methods *******************************
  53.  
  54. var
  55.   snd_pcm_open: function(pcm: PPsnd_pcm_t; Name: PChar; stream: snd_pcm_stream_t; mode: cint): cint; cdecl;
  56.  
  57. var
  58.   snd_pcm_set_params: function(pcm: Psnd_pcm_t; format: snd_pcm_format_t; access: snd_pcm_access_t; channels, rate: cuint; soft_resample: cint; latency: cuint): cint; cdecl;
  59.  
  60. var
  61.   snd_pcm_writei: function(pcm: Psnd_pcm_t; buffer: Pointer; size: snd_pcm_uframes_t): snd_pcm_sframes_t; cdecl;
  62.  
  63. var
  64.   snd_pcm_recover: function(pcm: Psnd_pcm_t; err, silent: cint): cint; cdecl;
  65.  
  66. var
  67.   snd_pcm_drain: function(pcm: Psnd_pcm_t): cint; cdecl;
  68.  
  69. var
  70.   snd_pcm_close: function(pcm: Psnd_pcm_t): cint; cdecl;
  71.  
  72. {Special function for dynamic loading of lib ...}
  73.  
  74. var
  75.   ab_Handle: TLibHandle = dynlibs.NilHandle; // this will hold our handle for the lib; it functions nicely as a mutli-lib prevention unit as well...
  76.  
  77. var
  78.   ReferenceCounter: cardinal = 0;  // Reference counter
  79.  
  80. function ab_IsLoaded: Boolean; inline;
  81.  
  82. function ab_Load: Boolean; // load the lib
  83.  
  84. procedure ab_Unload();     // unload and frees the lib from memory : do not forget to call it before close application.
  85.  
  86. function ALSAbeep(frequency, duration, volume: integer; warble: Boolean): Boolean;
  87.  
  88. implementation
  89.  
  90. function ab_IsLoaded: Boolean;
  91. begin
  92.   Result := (ab_Handle <> dynlibs.NilHandle);
  93. end;
  94.  
  95. function ab_Load: Boolean; // load the lib
  96. var
  97.   thelib: string = 'libasound.so.2';
  98. begin
  99.   Result := False;
  100.   if ab_Handle <> 0 then
  101.   begin
  102.     Inc(ReferenceCounter);
  103.     Result := True; {is it already there ?}
  104.   end
  105.   else
  106.   begin {go & load the library}
  107.     ab_Handle := DynLibs.SafeLoadLibrary(thelib); // obtain the handle we want
  108.     if ab_Handle <> DynLibs.NilHandle then
  109.     begin {now we tie the functions to the VARs from above}
  110.  
  111.       Pointer(snd_pcm_open)       := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_open'));
  112.       Pointer(snd_pcm_set_params) := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_set_params'));
  113.       Pointer(snd_pcm_writei)     := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_writei'));
  114.       Pointer(snd_pcm_recover)    := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_recover'));
  115.       Pointer(snd_pcm_recover)    := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_recover'));
  116.       Pointer(snd_pcm_drain)      := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_drain'));
  117.       Pointer(snd_pcm_close)      := DynLibs.GetProcedureAddress(ab_Handle, PChar('snd_pcm_close'));
  118.  
  119.     end;
  120.     Result           := ab_IsLoaded;
  121.     ReferenceCounter := 1;
  122.   end;
  123.  
  124. end;
  125.  
  126. procedure ab_Unload();
  127. begin
  128.   // < Reference counting
  129.   if ReferenceCounter > 0 then
  130.     Dec(ReferenceCounter);
  131.   if ReferenceCounter > 0 then
  132.     Exit;
  133.   // >
  134.   if ab_IsLoaded then
  135.   begin
  136.     DynLibs.UnloadLibrary(ab_Handle);
  137.     ab_Handle := DynLibs.NilHandle;
  138.   end;
  139. end;
  140.  
  141.  
  142. function ALSAbeep(frequency, duration, volume: integer; warble: Boolean): Boolean;
  143. var
  144.   buffer: array[0..9600 - 1] of byte;           // 1/5th second worth of samples @48000Hz
  145.   frames: snd_pcm_sframes_t;                    // number of frames written (negative if an error occurred)
  146.   pcm: PPsnd_pcm_t;                             // sound device handle
  147.   I, FC: integer;
  148.   SA: array[0..359] of shortint;                // array of sine wave values for a single cycle
  149. const
  150.   device = 'default' + #0;                      // name of sound device
  151. var
  152.   count1, count2, N, X: integer;
  153. begin
  154.   Result := False;
  155.  
  156.   ab_Load;
  157.  
  158.   if snd_pcm_open(@pcm, @device[1], SND_PCM_STREAM_PLAYBACK, 0) = 0 then
  159.     if snd_pcm_set_params(pcm, SND_PCM_FORMAT_U8,
  160.       SND_PCM_ACCESS_RW_INTERLEAVED,
  161.       1,                        // number of channels
  162.       48000,                    // sample rate (Hz)
  163.       1,                        // resampling on/off
  164.       500000) = 0 then            // latency (us)
  165.     begin
  166.       Result := True;
  167.  
  168.       frequency := abs(frequency);                                         // -\
  169.       duration  := abs(duration);                                           //   |-- ensure no parameters are negative
  170.       volume    := abs(volume);                                               // -/
  171.       if frequency < 20 then
  172.         frequency := 20;                                 // -\
  173.       if duration < 50 then
  174.         duration := 50;                                  //   |-- restrict parameters to usable ranges
  175.       if volume > 100 then
  176.         volume   := 100;                                    // -/
  177.  
  178.       for I := 0 to 359 do
  179.         SA[I] := round(sin(pi * I / 180.0) * volume);           // create sine wave pattern
  180.       X       := 0;
  181.       N       := 0;                                                              // up/down counter used by unequal interval division
  182.  
  183.       count1 := 0;                                                         // count1 counts up, count2 counts down
  184.       count2 := duration * 48;                                               // (at 48000Hz there are 48 samples per ms)
  185.  
  186.       while count2 > 0 do                                                  // start making sound!
  187.       begin
  188.         FC    := 0;
  189.         for I := 0 to sizeof(buffer) - 1 do                                  // fill buffer with samples
  190.         begin
  191.           if count2 > 0 then
  192.           begin
  193.             if count1 < 480 then
  194.               buffer[I] := 128 + ((count1 * SA[X]) div 480)
  195.             else   // 10ms feather in
  196.             if count2 < 480 then
  197.               buffer[I] := 128 + ((count2 * SA[X]) div 480)
  198.             else   // 10ms feather out
  199.               buffer[I] := 128 + SA[X];
  200.             if warble and odd(count1 div 120) then
  201.               buffer[I] := 128;              // 200Hz warble
  202.             Inc(FC);
  203.           end
  204.           else
  205.           begin
  206.             buffer[I] := 128;                             // no signal on trailing end of buffer, just in case
  207.             if (FC mod 2400) <> 0 then
  208.               Inc(FC);            // keep increasing FC until is a multiple of 2400
  209.           end;
  210.  
  211.           Inc(N, frequency * 360);                                          // unequal interval division routine
  212.           while (N > 0) do
  213.           begin                                           // (a variation on Bresenham's Algorithm)
  214.             Dec(N, 48000);
  215.             Inc(X);
  216.           end;
  217.           X := X mod 360;
  218.  
  219.           Inc(count1);
  220.           Dec(count2);
  221.         end;
  222.  
  223.         frames   := snd_pcm_writei(pcm, @buffer, max(2400, FC));             // write AT LEAST one full period
  224.         if frames < 0 then
  225.           frames := snd_pcm_recover(pcm, frames, 0);        // try to recover from any error
  226.         if frames < 0 then
  227.           break;                                            // give up if failed to recover
  228.       end;
  229.       snd_pcm_drain(pcm);                                                // drain any remaining samples
  230.       snd_pcm_close(pcm);
  231.     end;
  232.   ab_unload;
  233. end;
  234.  
  235. end.


And the main program:

Code: Pascal  [Select][+][-]
  1. program alsa_beep_test;
  2.  
  3. uses
  4. alsa_beep;
  5.  
  6. begin
  7. ALSAbeep(440, 100, 100, false);  
  8. end.

Here it works out of the box.
« Last Edit: October 25, 2020, 11:12:21 pm by Fred vS »
I use Lazarus 2.0.6 32/64 and FPC 3.2.0 32/64 on Debian 10.2 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs
https://gitlab.com/fredvs

winni

  • Hero Member
  • *****
  • Posts: 1993
Re: alsa beep - linux only
« Reply #29 on: October 25, 2020, 11:32:34 pm »
Hi!

There are a lot of boards around where the manufacturer is to greedy to install a beeper.
So they just switch the BIOS option to disabled.

Whatever you do: then there is no beeper.

xkbbell, XkbForceBell and XBell rely on the existence of a beeper.

So after a long discussion is again there where I started it:
With the support of Alsa.

Only that now Aplay is avoided.

The solution of Fred vS and Robert Rozee works out of the box.
Finally we got a nice and usefull unit.

Thanx!

Winni

 

TinyPortal © 2005-2018