I have an application which uses the Sound class to play a sequence of WAV files needed for some test applications. The program is working quite nicely with one exception. The Volume property is not quite what I expected. The LR says that Sound.Volume controls the volume of sound, and the the range is from 0 to 100. I would expect (apparently incorrectly) that when it says “controls” it would be somewhat of a linear control (e.g. 25 -> 25% vol, 50 -> 50% vol, 100 -> 100% vol). From all my trials (and tribulations) the control appears to operate only from about 80 to 100; and not linear at all. Most of the real control of the volume resides between 90 and 100. Is that the way it’s supposed to be? Right now, I am going down the path of generating my own WAV files at different “volumes”, which is working ok. But I would like to understand how the control should be expected to operate. Tested this behavior on Windows 7 and Windows 8.
When dealing with sound intensity (volume) logarithmic scales are applied. So, we use decibels (a logarithmic scale) to express volume because our volume sensation and the intensity of the volume (the energy of the sound wave) are not linearly proportional.
So, you expect your volume property to affect linearly, and maybe it is actually varying linearly the intensity, but what you perceive is not a linear variation.
If this is the case, you need to correct the Volume property for our non-linear preception. Also, if this is the case, I would fill a feature request since the usability of the volume property as it is now would be very low, in my opinion.
Julien, thanks for your input. I am not guessing or perceiving anything. I measured this with an oscilloscope; and it does not match any sort of linear taper or logarithmic taper function I know off. I am just trying to figure out how was it meant to work/operate and if someone else had experienced this.
This is not like a new function/class. It certainly does not behave like any of the volume controls on the computer, so I am asking for some feedback on some more experienced user of this class or maybe a Xojo Engineer on what the expectation of that property should be.
I fully agree with you. But since this is my first foray on using this function, perhaps there are others out there with better ideas on how to improve its use (or use it properly).
It does make some difference, but doesn’t really address the issue. There is no usable range. Let me illustrate with an example. Below is some sample data using a 1kHz tone:
Sorry for the gross table formatting, but at the moment I can’t access any file sharing site to post a graphic. But you can see, the latter set is as would be expected (and more important useable) and the former set is really not useable (at best is equivalent to 5-bit resolution - i.e. 32 discrete levels, and they are not even linear). It’s almost the same as just providing two states for the volume: on and off.
I am switching over to using the MoviePlayer which does seem to work as expected (except for the looping which does not seem to be working at the moment - trying to figure out why). But my question really is about the expected operation of the Sound Class. Maybe I am completely misreading its use in the LR.
The first set of data follows this equation: Output=0.00439EXP(0.112889Volume)
Your lower output values might be read as zero due to hardware limitations (the output values should be below 3 mVrms). This output is what I would expect, as this should provide a linear perception of the sound volume.
I got that expression from Excel, doing a regression. EXP is the same as e^ (also in Xojo).
Vrms is an average voltage of a wave shaped voltage signal (the one sent to the speakers). mV rms is the same, but in miliVolts instead of Volts.
Since the Log function in Xojo is the natural logarithm (usually expressed as Ln), you don’t need to convert the base of the logarithm (although it has no effect on the result as ln e equals 1). I have also used the original 0.00439 and 3.52 values for the sake of clarity:
Julen / Will ,
Thanks for taking the time to look at this.
Same thing I used. It was nice to get a function that went with it, but the function itself made no difference (for my application). It follows no normal audio taper functions I have seen (and we have done many audio panels at work).
This snippet is cool conceptually, but it is doesn’t address the problem in real life (please take no offense); let me explain. This (similar equation to what you have) is what I started with, I mapped the sound function and made up an equation so I could attempt to gain some usefulness out of the function. But the Sound.Volume takes 100 discrete values. The discrete part is important. Once you apply the function you provided (and which is mathematically correct), only about a third of those values are actually meaningful. In other words, only values from about 70 to 100 are actually used, and the rest of the values are essentially thrown away. It would be awesome if Sound.Volume allowed fractional numbers between 70 and 100, but all you get is 30 values to control the volume (and they are not linear). That limits the real usefulness (and in no way matches the LR). Again, I am not trying to diminish what you have expressed there. I came to a very similar conclusion, but the usefulness of the function goes away since you can barely control the output. I mean you have some control, but very, very coarse.
Since Will says it plays ok (sounds linear) on the Mac (not a surprise), and if it did not you would be able to discern it (the ear+brain is a wonderful thing); I will assume the damn Windows implementation is broken (not a surprise I guess). I was hoping I was missing something obvious. The Sound object is probably not used much (in Windows), cause anyone trying to control the volume would’ve heard this I think.
As for how I was using this; I needed to play 4 nearly simultaneous tones and individually control their volumes. The Sound object seemed to be great for this (guess not). I have reconsidered my approach based on this Xojo limitation on the Windows implementation.
BTW, the declare to control the volume (in Windows) follows (credits to Barry Traver): Soft Declare Function waveOutSetVolume Lib "winmm" ( devid as Integer, vol as Integer ) As Integer
Dim outVolume As Integer
Dim state As Integer
// volume is 32bits, 16bits for left channel, and 16bits for right channel
// intendedVolume is an integer value from 0 to 100
outVolume = intendedVolume * (&hFFFFFFFF / 100)
state = waveOutSetVolume(0, outVolume)
Thank for the help. When I get a chance I will create a ticket and throw it into the Windows black hole for a rainy day.