Ask Reuben

Sound

How do I make a sound in a Genero application ?

Sound can be played by Genero applications through the playSound front-call.  Like images, the key point is to get the sound file from the back-end to the front-end.  Your sound file will typically be bundled in with the rest of your application files on the back-end server but needs to be on the front-end server in order for the end user to hear the sound.

Historically that might have meant code similar to the following …

CALL ui.Interface.frontCall("standard","feInfo",["dataDirectory"],[l_data_directory])
LET l_destination_file = l_data_directory CLIPPED, l_source_file
CALL FGL_PUTFILE(l_source_file,l_destination_file)
CALL ui.Interface.frontCall("standard", "playSound",[l_destination_file], [])

… to copy a sound file to the front-end and then play it with the front call.

With GAS the ui.Interface.filenameToUri method can be used like it can with images, reports etc to have files stored on the back-end and silently copied from the back-end to the front end so the front end can view/play/use etc them

LET l_destination_file = ui.Interface.filenameToURI(l_source_file)
CALL ui.Interface.frontCall("standard", "playSound", l_destination_file, [])

Typically sound is not a key feature of business applications.  It has also has not had much in common across the various front-end.  You should check how your front-end handles various formats such as mp3, wav etc as what plays on one front end might not have historically played on another front-end.  For these reasons there has not been a lot of time spent on sound.  With the move to Universal Rendering, you may find it easier to introduce more sound functionality due to the Web Audio API that has strong browser compatibility.

For example using Oscillator Node I could create tones as a custom front-call for GBC/Universal Rendering.  What I liked about this was that it did not require sound files.

With the following in my custom front-call javascript file …

beep: function (volume, frequency, type, duration) {

    var AudioContext = window.AudioContext || window.webkitAudioContext;
    var audioCtx = new AudioContext();

    var oscillator = audioCtx.createOscillator();
    var gainNode = audioCtx.createGain();

    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);

    gainNode.gain.value = volume;
    oscillator.frequency.value = frequency;
    oscillator.type = type;

    oscillator.start();

    setTimeout(
        function() {
            oscillator.stop();
        },
        duration
    );
    return ["0"];
},

I could call that with the following 4gl …

 CALL ui.Interface.frontCall("my_custom_frontcall_module","beep",[1, 440, "sine", 1000],[])

… to play a tone with frequency of 440 Hz (the A below middle C) for a duration of 1000 milliseconds.  To play different tones is simply a case of changing the parameters.

An example like this shows the benefits of Universal Rendering in that this would be expected to work across all our front-ends.

The WebAudio API probably has a lot of functionality if you dig into it, and I think my beep example above is the tip of the iceberg.

On Genero Mobile devices, you also have the option of using the Cordova media plugin to play audio on mobile devices.

I know there were a few enhancement requests in the system around sound.  With Universal Rendering we may look at them closer as we can now offer a universal solution but looking at the beep example it is something you can also look at as a custom front-call to get exactly what you want.

P.S. A funny story involving  sound.  When I did my first transformation to Genero in the early 2000’s my employer at the time saved a little money by not having any sound cards in the PC’s in the office.  We noticed that ERROR and MESSAGE had different properties in that the text with an ERROR would only stay on screen until the next user interaction, whilst text for a MESSAGE would stay on screen  until the next MESSAGE.  There was a range of messages that we thought we could change to use error and not have to worry about explicitly clearing the messages, and so we changed these from MESSAGE to ERROR.  As we did not have sound cards we did not realise that GDC had an audio beep that sounded with ERROR.  So the first end user tests reported that there was a lot of beeps from these messages that were turned to errors  that we were not hearing because we had no sound cards in the office!!!