[comp.windows.x] X11R5 wish: better sound

roger@hpnmdla.HP.COM (Roger Petersen) (08/01/90)

I'd like an easier, better sounding way of playing music or generating
tones in X11.

Right now, there's the XBell() and XChangeKeyboardControl() functions,
which allow setting the pitch, duration, and volume, and then generating
the sound.

This makes it hard to do anything more than just beep, since the XBell()
calls are executed asynchronously.  I wrote a simple program called xmorse
that generates Morse code, and the code sounds pretty crappy.  The same
is true when trying to play a melody.  It's really choppy.

(I'm using XChangeKeyboardControl to set up the tone and duration, then
XBell to make the sound.  Then I use a select() call to sleep until
the tone's duration is complete.  Is there a better way?)

	--------------------------------------------

What I'd really like is a way to pass the XBell() routine (or maybe some
*new* XSound() routine) a pointer to an array of tones structs.  The
structure could be the same as the XKeyboardControl structure, or maybe a
simpler one:

	typedef struct {
	        int bell_percent;
	        int bell_pitch;
	        int bell_duration;
	} XBellTone;   /* pick your favorite name here */

Then I could simply pass the XSound() routine a pointer to an array of
XBellTones, and it would play the tones synchronously, one after the other.
For pauses, the bell_pitch would simply be set to full off.

[Notice that I didn't ask for support for multipe voices, noise sources,
streams of digitized sound, etc.  These *could* be considered too...]

	--------------------------------------------

Has anyone else wrestled with generating sounds in X?

Roger Petersen
roger@hpnmdla.hp.com

john@acorn.co.uk (John Bowler) (08/02/90)

In article <990003@hpnmdla.HP.COM> roger@hpnmdla.HP.COM (Roger Petersen) writes:
>I'd like an easier, better sounding way of playing music or generating
>tones in X11.
>
>Right now, there's the XBell() and XChangeKeyboardControl() functions,
>which allow setting the pitch, duration, and volume, and then generating
>the sound.

But which give absolutely no guarantees that the server will be able
to do this and, worse, there is no way of finding out what the server will
do.

>What I'd really like is a way to pass the XBell() routine (or maybe some
>*new* XSound() routine) a pointer to an array of tones structs.  The
>structure could be the same as the XKeyboardControl structure, or maybe a
>simpler one:
>
>	typedef struct {
>	        int bell_percent;
>	        int bell_pitch;
>	        int bell_duration;
>	} XBellTone;   /* pick your favorite name here */
>
>Then I could simply pass the XSound() routine a pointer to an array of
>XBellTones, and it would play the tones synchronously, one after the other.
>For pauses, the bell_pitch would simply be set to full off.
>
>[Notice that I didn't ask for support for multipe voices, noise sources,
>streams of digitized sound, etc.  These *could* be considered too...]

The more you ask for, the less likely you are that any server can
do it...  We've just finished developing an extension similar to
the above which takes ``sounds'' expressed as 8, 16 or 32 bit
samples and allows them to be ``played''.  The extension gives
considerable freedom to the server (eg, the sounds won't necessarily
be played one after the other, the server might even stop doing
anything else while playing the sound, you may not get any choice
about sample rate and so on).  The client can find out about this
and choose not to use the interface if it wants.

The current API is crude (Xlib level), the only server implementation
is for our own hardware.  I will make the details public if anyone
is interested.  The extension name (*NOT* yet registered; although
our manufacturer prefix is) is Acorn-Noise.

John Bowler (jbowler@acorn.co.uk)

roger@hpnmdla.HP.COM (Roger Petersen) (08/07/90)

In comp.windows.x, john@acorn.co.uk (John Bowler) writes:

> >Right now, there's the XBell() and XChangeKeyboardControl() functions,
> >which allow setting the pitch, duration, and volume, and then generating
> >the sound.
> 
> But which give absolutely no guarantees that the server will be able
> to do this and, worse, there is no way of finding out what the server will
> do.
> The more you ask for, the less likely you are that any server can
> do it... 

True.  But *if* the server can perform these functions, it shouldn't take
much more to perform the same function using an array for input.  And if the
server can't deal with sound, it can ignore/alter the array commands just
like it does the existing sound commands.


>                                            The extension gives
> considerable freedom to the server (eg, the sounds won't necessarily
> be played one after the other, the server might even stop doing
> anything else while playing the sound, you may not get any choice
> about sample rate and so on).

I wouldn't have guessed that generating the sounds in the proper order would
have been the main difficulty.  If anything, I guessed that generating them
in a single, fluid, continuous stream would have been the challenge.

A command that accepts an array of tones for input wouldn't be required
to generate them smoothly and synchronously.  However, a server that had
a good, smooth XSound()/whatever command would allow for some impressive
musical programs.


So now let's talk about handling multiple voices, noise, sustain, decay... :-)

Roger Petersen

john@acorn.co.uk (John Bowler) (08/08/90)

In article <990004@hpnmdla.HP.COM> roger@hpnmdla.HP.COM (Roger Petersen) writes:
>In comp.windows.x, john@acorn.co.uk (John Bowler) writes:
>
>>...
>> The more you ask for, the less likely you are that any server can
>> do it... 
>
>True.  But *if* the server can perform these functions, it shouldn't take
>much more to perform the same function using an array for input.  And if the
>server can't deal with sound, it can ignore/alter the array commands just
>like it does the existing sound commands.

True (it is very easy, you just ignore all channels but one, or
add them together depending on how nice you want to be).  However
I had to decide where to stop - the aim of the extension is to
enhance the faciltiies for audio *feedback* to the user, I couldn't
demonstrate a need for stereo (etc) so I didn't do it.

>>                                            The extension gives
>> considerable freedom to the server (eg, the sounds won't necessarily
>> be played one after the other, the server might even stop doing
>> anything else while playing the sound, you may not get any choice
>> about sample rate and so on).
>
>I wouldn't have guessed that generating the sounds in the proper order would
>have been the main difficulty.

I didn't express this very clearly.  The server is allowed to
*merge* successive sound requests rather than delaying a second
one until the first is finished.  The definition of ``merge'' in
this context is open - the server can simply forget about the first
request and play the second in its place.  It can also discard a
second request while the first is playing.  (Nasty, but some hardware
might force either behaviour).

>                                If anything, I guessed that generating them
>in a single, fluid, continuous stream would have been the challenge.

Indeed it is.  Our current implementation can suffer from clicks in the
output if given a lot of noises to play.  What a pity :-).

>A command that accepts an array of tones for input wouldn't be required
>to generate them smoothly and synchronously.  However, a server that had
>a good, smooth XSound()/whatever command would allow for some impressive
>musical programs.
>
>So now let's talk about handling multiple voices, noise, sustain, decay... :-)

Yes, exactly - this is what the extension is *not* designed to do.  The
concession to this is that the extension (and XBell) can be switched *off* -
this causes the server to relinquish control of any sound hardware, so it
can then be used by a program which offers a higher quality interface.

The real problem is that any good musical reproduction can require a very
large amount of data.  Although many servers may be able to deal with the
overhead of such data, many may not - even though they can offer much better
sound facilities than XBell.  The Acorn-Noise extension tries to provide
sufficient facilities to enable production of useful audio feedback without
encouraging clients to attempt to play significant amounts of sound, so that
any client which chooses to use the extension is unlikely to stress it to the
point where some servers will be damaged by it.

John Bowler (jbowler@acorn.co.uk)