Recent

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

MarkMLl

  • Hero Member
  • *****
  • Posts: 1462
Re: alsa beep - linux only
« Reply #30 on: October 26, 2020, 09:10:10 am »
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.

Which was the point I was trying to make. I never said I was against ALSA, what I didn't like was (a) having to invoke aplay and apply it to a media file (neither of which can be relied on to exist in the general case) and (b) the heavyweight alsapas library.

I'm still looking at whether it's possible to decide whether a (GUI) program has been invoked in a way that means that a bell through Write() will work. However there's a problem here that (i) it relies on Konsole or something similar as a parent and (b) something can be interposed between Konsole and the program which prevents the bell getting through to Konsole (hence the theme handlers and ALSA) without leaving any trace (e.g. all of the XDG environment variables are still defined). I'll ask on the XDG mailing list when I have time (possibly later today) but for the moment the best I can offer is that if an app's parent is a shell and its grandparent Konsole etc. then in principle the user can set up Write(Bell) to go via the themes to ALSA, and if it's not then Write(Bell) will probably be silent.

It certainly appears that the X11 bell is too erratic to be useful.

MarkMLl
« Last Edit: October 29, 2020, 10:11:13 am 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.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2429
  • Compiler Developer
Re: alsa beep - linux only
« Reply #31 on: October 26, 2020, 09:19:41 am »
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.

Most boards still have the speaker header and nothing is switched off in the BIOS. Only Laptops might have different solutions (e.g. in mine from ~2005 even POST Beeps are routed through the soundcard).

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

No, they don't. As always it's a question of how the system (in this case both X11 and the sound system) is configured.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1462
Re: alsa beep - linux only
« Reply #32 on: October 26, 2020, 09:42:25 am »
No, they don't. As always it's a question of how the system (in this case both X11 and the sound system) is configured.

And discussion of this gets back to one of the things that (IMO and with respect to Winni) made aplay such a bad idea: far too much depends on how well the distro is put together, and on /exactly/ what packages have been installed by the system owner.

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.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1462
Re: alsa beep - linux only
« Reply #33 on: October 26, 2020, 12:10:11 pm »
Attached is my current take on this. It's got both static and dynamic libraries (although in practice dynamic is vastly preferable- thanks Fred), it's got Robert's original demo function (with some tweaks I did yesterday evening between other things) plus Fred's which has some extra frills. Lazarus project plus simple .pas file which compiles standalone.

Tested on Debian "Buster" (stable) x86_64 KDE.

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: 1983
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #34 on: October 26, 2020, 12:48:38 pm »
Attached is my current take on this. It's got both static and dynamic libraries (although in practice dynamic is vastly preferable- thanks Fred), it's got Robert's original demo function (with some tweaks I did yesterday evening between other things) plus Fred's which has some extra frills. Lazarus project plus simple .pas file which compiles standalone.

Tested on Debian "Buster" (stable) x86_64 KDE.

MarkMLl

Hello.

Nice.

Note that with the static loading version, due to a very sad restriction of fpc, you will oblige people to install the libasound-dev package or create a symlink  (libasound.so --> libasound.so.2).
« Last Edit: October 26, 2020, 12:50:17 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: 1462
Re: alsa beep - linux only
« Reply #35 on: October 26, 2020, 01:06:58 pm »
Nice.

Note that with the static loading version, due to a very sad restriction of fpc, you will oblige people to install the libasound-dev package or create a symlink  (libasound.so --> libasound.so.2).

Thanks for the appreciative comment. This has generated a painful amount of grief, and it would be nice to get it sorted out.

Is the symlink problem really down to FPC, or is it really a distreaux issue since some (but not necessarily all) don't create it until the -dev is installed? This sort of thing has caused a lot of problems with- in particular- database libraries in the past, and it would be nice if there were some way of sorting it out for good.

Obviously in the current case the dynamic variant is preferable, and TBH I'd prefer to put (my derivative of) Robert's function on there since it's sufficiently simple that anybody who's wavering on linking to ALSA can't claim that we're hiding anything dubious.

This has been a very useful exercise, and I might see if I can do anything comparable for the ALSA MIDI functions. The usual alsapas library is pretty horrid, when setting it up you have to run a script so it can work out what version of the ALSA libraries/headers are on the development system... which have to match the target system.

I think the more people that can test the current code on different distreaux and versions the better.

MarkMLl
« Last Edit: October 29, 2020, 10:11:35 am 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: 1983
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #36 on: October 26, 2020, 01:12:35 pm »
Quote
Is the symlink problem really down to FPC, or is it really a distreaux issue since some (but not necessarily all) don't create it until the -dev is installed? This sort of thing has caused a lot of problems with- in particular- database libraries in the past, and it would be nice if there were some way of sorting it out for good.

https://bugs.freepascal.org/view.php?id=32367

More than 3 years ago already, time goes fast.

 :'(
« Last Edit: October 26, 2020, 01:14:08 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: 1462
Re: alsa beep - linux only
« Reply #37 on: October 26, 2020, 01:59:35 pm »
Quote
Is the symlink problem really down to FPC, or is it really a distreaux issue since some (but not necessarily all) don't create it until the -dev is installed? This sort of thing has caused a lot of problems with- in particular- database libraries in the past, and it would be nice if there were some way of sorting it out for good.

https://bugs.freepascal.org/view.php?id=32367

More than 3 years ago already, time goes fast.

I've been here before, but I can't remember in what context. Any build-time linkage to a .so.n file is /wrong/, and I don't care if it is "the unix way". And having the linker resolve a symlink to an actual .so is also /wrong/: this should be done at load time, and if the OS can't mediate an API negotiation between the app and a library then that is the time it should complain.

But in reality, I think that the "missing symlink" problem is a distro issue.

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.

winni

  • Hero Member
  • *****
  • Posts: 2009
Re: alsa beep - linux only
« Reply #38 on: October 26, 2020, 10:02:33 pm »
@Fred vS

Hi!

After reading the code of unit alsa_beep I could not resist to create a nice enhancement:

I created
Code: Pascal  [Select][+][-]
  1. function ALSAglide(StartFreq,EndFreq, duration, volume: integer): Boolean;

The  musicians call it glissando.
The Frequency is moving from StartFreq to EndFreq in duration time.

As your code is very well structured I only hat to add 2 variables and 3 lines of code.
And I simplified the range checking.

Winni

Code: Pascal  [Select][+][-]
  1. function ALSAglide(StartFreq,EndFreq, duration, volume: integer): Boolean;
  2. var
  3.   buffer: array[0..9600 - 1] of byte;           // 1/5th second worth of samples @48000Hz
  4.   frames: snd_pcm_sframes_t;                    // number of frames written (negative if an error occurred)
  5.   pcm: PPsnd_pcm_t;                             // sound device handle
  6.   I, FC: integer;
  7.   SA: array[0..359] of shortint;                // array of sine wave values for a single cycle
  8. const
  9.   device = 'default' + #0;                      // name of sound device
  10. var
  11.   count1, count2, N, X: integer;
  12.   DeltaStep: single;   //winni
  13.   delta : Integer;     //  "
  14. begin
  15.   Result := False;
  16.  
  17.   ab_Load;
  18.  
  19.   if snd_pcm_open(@pcm, @device[1], SND_PCM_STREAM_PLAYBACK, 0) = 0 then
  20.     if snd_pcm_set_params(pcm, SND_PCM_FORMAT_U8,
  21.       SND_PCM_ACCESS_RW_INTERLEAVED,
  22.       1,                        // number of channels
  23.       48000,                    // sample rate (Hz)
  24.       1,                        // resampling on/off
  25.       500000) = 0 then            // latency (us)
  26.     begin
  27.       Result := True;
  28.       StartFreq:= EnsureRange(abs(StartFreq),20,20000);
  29.       EndFreq  := EnsureRange(abs(EndFreq),20,20000);
  30.       duration := EnsureRange(abs(duration),50,maxint);// 24.85 days
  31.       volume   := EnsureRange(abs(Volume),0,100);
  32.       // 48 samples per ms -->
  33.       // 360 / 48 = 7.5
  34.       DeltaStep := 7.5*(EndFreq - startFreq) /(duration);   // winni
  35.  
  36.       for I := 0 to 359 do
  37.         SA[I] := round(sin(pi * I / 180.0) * volume);           // create sine wave pattern
  38.       X       := 0;
  39.       N       := 0;                                                              // up/down counter used by unequal interval division
  40.  
  41.       count1 := 0;                                                         // count1 counts up, count2 counts down
  42.       count2 := duration * 48;                                               // (at 48000Hz there are 48 samples per ms)
  43.  
  44.       while count2 > 0 do                                                  // start making sound!
  45.       begin
  46.         FC    := 0;
  47.         for I := 0 to sizeof(buffer) - 1 do                                  // fill buffer with samples
  48.         begin
  49.           if count2 > 0 then
  50.           begin
  51.             if count1 < 480 then
  52.               buffer[I] := 128 + ((count1 * SA[X]) div 480)
  53.             else   // 10ms feather in
  54.             if count2 < 480 then
  55.               buffer[I] := 128 + ((count2 * SA[X]) div 480)
  56.             else   // 10ms feather out
  57.               buffer[I] := 128 + SA[X];
  58.             Inc(FC);
  59.           end
  60.           else
  61.           begin
  62.             buffer[I] := 128;                             // no signal on trailing end of buffer, just in case
  63.             if (FC mod 2400) <> 0 then
  64.               Inc(FC);            // keep increasing FC until is a multiple of 2400
  65.           end;
  66.  
  67.          delta := round (Count1*DeltaStep);   // winni
  68.          Inc(N,StartFreq*360+Delta);          // winni
  69.           while (N > 0) do
  70.           begin                                           // (a variation on Bresenham's Algorithm)
  71.             Dec(N, 48000);
  72.             Inc(X);
  73.           end;
  74.           X := X mod 360;
  75.  
  76.           Inc(count1);
  77.           Dec(count2);
  78.         end;
  79.  
  80.         frames   := snd_pcm_writei(pcm, @buffer, max(2400, FC));             // write AT LEAST one full period
  81.         if frames < 0 then
  82.           frames := snd_pcm_recover(pcm, frames, 0);        // try to recover from any error
  83.         if frames < 0 then
  84.           break;                                            // give up if failed to recover
  85.       end;
  86.       snd_pcm_drain(pcm);                                   // drain any remaining samples
  87.       snd_pcm_close(pcm);
  88.     end;
  89.   ab_unload;
  90. end; //AlsaGlide
  91.  
  92.  
     

Fred vS

  • Hero Member
  • *****
  • Posts: 1983
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #39 on: October 26, 2020, 10:10:08 pm »
@Winni: EXCELLENT.

Do you have a GitHub account?

If yes, it would be good to add it.

If no, if you agree, I will add it to this (and maybe rename into alsa_sound, adding some fast methods, like alsa_beep, alsa_glide, alsa_blabla, etc...):

https://github.com/fredvs/alsa_beep

[EDIT]
Quote
As your code is very well structured I only hat to add 2 variables and 3 lines of code.

Huh, it is the code of Robert Rozee and it shows a highest skill.
@Robert Rozee many thanks for your providential perfect code.

Fre;D

« Last Edit: October 26, 2020, 10:32:22 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: 2009
Re: alsa beep - linux only
« Reply #40 on: October 26, 2020, 10:29:58 pm »
@Fred vS

Hi!

No, I don't have a GitHub account.

Add it to your unit!
And now I know how to handle the Alsa lib!

Winni

Fred vS

  • Hero Member
  • *****
  • Posts: 1983
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #41 on: October 26, 2020, 10:36:02 pm »
Hello Winni.

Quote
Add it to your unit!

Yep, thanks!

Quote
And now I know how to handle the Alsa lib!

Yes, me too and this thanks to Robert Rozee.

Many, many wow and thanks Rob!

Fre;D
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: 1462
Re: alsa beep - linux only
« Reply #42 on: October 27, 2020, 12:13:24 pm »
I'd suggest that while vibrato, glissando etc. are great fun, they're outside the remit of getting a (Lazarus) program to beep on Linux.

It does suggest however that there's a lot of merit in the idea of exposing Fred's modification of Robert's consolidation of (whoever's) cut-down ALSA interface library so that other programs can use 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: 1983
    • StrumPract is the musicians best friend
Re: alsa beep - linux only
« Reply #43 on: October 27, 2020, 12:31:25 pm »
Quote
I'd suggest that while vibrato, glissando etc..

Yes good idea.

I added ALSAbeeperStereo(), a stereo beeper with custom frequency for each channel.

https://github.com/fredvs/alsa_sound

Fre;D
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

lucamar

  • Hero Member
  • *****
  • Posts: 3236
Re: alsa beep - linux only
« Reply #44 on: October 27, 2020, 12:40:14 pm »
https://github.com/fredvs/alsa_sound

Fre;D

Totally off-topic and, please, excuse me for that but in your repo, what's dummy.txt for?
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018