[Sound-open-firmware] [PATCH 2/4] Tone: Add channel specific volume plus other fixes

Seppo Ingalsuo seppo.ingalsuo at linux.intel.com
Thu Jun 22 13:50:09 CEST 2017


On 22.06.2017 12:02, Takashi Iwai wrote:

> On Thu, 22 Jun 2017 10:47:54 +0200,
> Seppo Ingalsuo wrote:
>>
>>
>> On 22.06.2017 11:28, Takashi Iwai wrote:
>>> On Thu, 22 Jun 2017 10:04:27 +0200,
>>> Seppo Ingalsuo wrote:
>>>> On 22.06.2017 04:31, Keyon Jie wrote:
>>>>> On 2017年06月22日 01:12, Seppo Ingalsuo wrote:
>>>>>> The mono tone level can be controlled per channel. A similar channel map
>>>>>> feature as in the volume component was added into volume command of
>>>>>> tone.
>>>>>>
>>>>>> The default tone frequency of 997 Hz was updated to a proper Q16.16
>>>>>> value.
>>>>>>
>>>>>> Moved tone function pointer set to tone_new() since it is not modified
>>>>>> later.
>>>>>>
>>>>>> Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
>>>>>> ---
>>>>>>     src/audio/tone.c | 56
>>>>>> ++++++++++++++++++++++++++++++++++++++++++--------------
>>>>>>     1 file changed, 42 insertions(+), 14 deletions(-)
>>>>>>
>>>>>> diff --git a/src/audio/tone.c b/src/audio/tone.c
>>>>>> index f45d8be..d1c7468 100644
>>>>>> --- a/src/audio/tone.c
>>>>>> +++ b/src/audio/tone.c
>>>>>> @@ -56,7 +56,8 @@
>>>>>>       #define TONE_NUM_FS            13       /* Table size for 8-192
>>>>>> kHz range */
>>>>>>     #define TONE_AMPLITUDE_DEFAULT 2147484  /* -60 dB from full scale */
>>>>>> -#define TONE_FREQUENCY_DEFAULT 16334848 /* 997 in Q18.14 */
>>>>>> +#define TONE_FREQUENCY_DEFAULT 65339392 /* 997 Hz in Q16.16 */
>>>>>> +#define TONE_VOLUME_DEFAULT 65536       /* 1.0 in Q16.16 */
>>>>> will they be more readable in hexadecimal?
>>>> Unfortunately the C preprocessor doesn't process float to fixed math
>>>> so I can't use any nice macro to create these. In hex it would look
>>>> like this and in my opinion it's not any better. The Q notation is
>>>> only sometimes by chance such that integer and decimal bits are not
>>>> mixed into same hex digit. For frequency Qx.y notation the used x is
>>>> sufficient to get to ultrasound frequencies and y to make precise
>>>> enough sweeps.
>>>>
>>>> #define TONE_AMPLITUDE_DEFAULT 0x20C49C  /* -60 dB from full scale */
>>>> #define TONE_FREQUENCY_DEFAULT 0xF940000 /* 997 Hz in Q18.14 */
>>>> #define TONE_FREQUENCY_DEFAULT 0x3E50000 /* 997 Hz in Q16.16 */
>>>> #define TONE_VOLUME_DEFAULT 0x10000       /* 1.0 in Q16.16 */
>>>>
>>>> To convert these with any calculator to floats when debugging code
>>>> (these are fractional numbers) there's extra effort needed with hex so
>>>> I definitely prefer decimal. Hex is good for bit masks but these are
>>>> not such.
>>> It's a fixed-point, so you can introduce a simple macro like
>>>
>>> #define TONE_FREQ_SHIFT		16
>>> #define TONE_FREQ(x, y)		((x) << TONE_FREQ_SHIFT | (y))
>>>
>>> then TONE_FREQUENCY_DEFAULT will be TONE_FREQ(997, 0), and so on.
>>> If you need to change the base shift, just change the TONE_FREQ_SHIFT
>>> and the rest remains as is.
>> Yes, that works for integers and it is readable but the needed
>> frequencies are often decimal numbers in Hz. E.g. C5 note is 523.251
>> Hz or if a sweep is started from 4th third octave band the frequency
>> would be 31.5 Hz.
> Yeah, the decimal point is tricky.
>
>> So I myself do with Octave that I use as pocket calculator
>>>> printf('%d\n',round(523.251*2^16))
>> 34291778
>>>> printf('%d\n',round(31.5*2^16))
>> 2064384
>>>> printf('%d\n',round(10^(-60/20)*2^31))
>> 2147484
> I thought C compiler (not preprocessor) should optimize the conversion
> and handle as an integer constant.
>
> #define TONE_FREQ(f)	(int)((f) * (2 << 16))	/* f = float */
>
> and
> 	int x = TONE_FREQ(523.251);
>
> should be converted to
>
> 	int x = 34291778;

Thanks, that works. At least with the compiler that I use 
(http://alsa-project.org/main/index.php/Firmware) the optimizing does 
the conversion to fixed without increase of the firmware image size. I 
also checked from disassembly that this part of the code remains 
identical. I did a minor fix and added rounding into the macro since 
compiler doesn't round the cast to int:

#define TONE_FREQ(f)    (int)((f) * (1 << 16))    /* f = float */

#define TONE_FREQ(f)    (((int)((f) * (1 << 17)) + 1) >> 1)  /* f = float */

If there's no concern from other people who know better the compilers 
I'm OK to make this change to increase readability and help avoiding 
mistakes with frequencies.

Seppo


>
>
> Takashi
>



More information about the Sound-open-firmware mailing list