Implementation of Wince volume adjustment

Source: Internet
Author: User
Tags case statement

From: http://hi.baidu.com/%BC%F2%B5%A5%B1%F9%D0%C4/blog/item/fa7a89d21ba5522f9a502720.html

On the wince platform, you can adjust the system volume by setting the volume adjustment button on the control panel. At the same time, if you use some media players, such as mplayer, You can independently adjust the input audio stream without affecting other system volume. We can understand the entire architecture as a Windows platform. You can set the volume of the entire system by setting the sound button in the lower-right corner. When playing a video such as a quiet listen or storm, you can set the volume of the software separately without affecting the volume of the entire system. The volume adjustment model of Wince is exactly like this.
Professional audio chips are used on the host machine, such as uda1341, wm8976, and wm9713. These chips have I2C interfaces for the processor to set the registers of the chip to adjust the volume. In the underlying driver, the corresponding interface is left to adjust the volume in the control panel, and finally adjust the register of the audio chip to adjust the volume.
This is the most common method. However, in order to save costs, Some OEMs make a big fuss about the hardware. The selected audio chip does not have the volume adjustment function at all, or even has no I2C interface. There is only one I2S interface for audio decoding. At this time, can wince adjust the volume as previously done? The answer is yes.
In wavemain. CPP, the volume adjustment procedure is as follows:
Case wodm_getvolume: // obtain the speaker volume
{
Pulong pdwgain = (Pulong) dwparam1;

If (pstreamcontext)
{
* Pdwgain = pstreamcontext-> getgain ();
}
Else
{
// Handle device gain in hardware
// * Pdwgain = g_phwcontext-> getoutputgain (); // no support for hardware volume adjustment
// Handle device gain in Software
Devicecontext * pdevicecontext = g_phwcontext-> getoutputdevicecontext (udeviceid); // obtain the soft volume
* Pdwgain = pdevicecontext-> getgain ();
}
Dwret = mmsyserr_noerror;
Break;
}

Case wodm_setvolume: // set the volume.
{
Long dwgain = dwparam1;
If (pstreamcontext) // If audio streams exist, adjust the audio stream volume here
{
// Retailmsg (1, (_ T ("stream volume set... \ n"); // lqm test.
Dwret = pstreamcontext-> setgain (dwgain); // dwgain = dwparam1, Which is input by the application layer such as mplayer.
// Retailmsg (1, (_ T ("stream volume set dwret = % d \ n"), dwret); // lqm test.
}
Else // if there is no audio stream, adjust the volume through the control panel to control the volume.
{
// Retailmsg (1, (_ T ("Hardware volume set... \ n"); // lqm test.
// Handle device gain in hardware
// Dwret = g_phwcontext-> setoutputgain (dwgain); // If the audio chip has the volume adjustment function, use hard tuning.
// Handle device gain in Software
Devicecontext * pdevicecontext = g_phwcontext-> getoutputdevicecontext (udeviceid );
Dwret = pdevicecontext-> setgain (dwgain); // The soft algorithm is used because the audio chip does not have the volume adjustment function.
}
Break;
}
The first case: wodm_getvolume is used to obtain the current volume. Note that in else, there are two functions: getoutputgain () and getgain. The previous function is used to obtain the hardware volume, that is, the audio chip volume, and the subsequent function is used to obtain the software volume, that is, the audio stream volume. If the audio chip has the volume adjustment function, use the first function. Otherwise, use the second function.
The second case: wodm_setvolume is used to set the volume. Similarly, in else, there are two functions: setoutputgain and setgain. The preceding function is used to set the hardware gain, that is, the audio chip register. If the audio chip does not support the volume adjustment function, use the following function. This function is used to set the volume soft.
In the second case, there is an if judgment statement with the position pstreamcontext. That is to say, if an audio stream exists, that is, when the audio file is being played, if this case statement is called, The if program is called to set the volume; otherwise, the else statement is called. If the soft setting method is used, both of them are completed through the gainchange function. The code of this function is as follows:
Virtual void gainchange ()
{
M_fxpgain = mapgain (m_dwgain); // m_fxpgain stores the volume of the audio stream
}
Here m_dwgain = dwgain = dwparam1. In the handlewavemessage function, we can see that dwparam1 = pparams-> dwparam1; that is, m_dwgain is the value passed by the application. For example, through mplayer, the volume setting button of the control panel.
Go to the mapgain function:
DWORD streamcontext: mapgain (DWORD gain) // gain is input by the application layer, such as a media player, if there is an audio stream.
{
DWORD totalgain = gain & 0 xFFFF;
DWORD secondarygain = m_pdevicecontext-> getsecondarygainlimit (m_secondarygainclass) & 0 xFFFF;

// Retailmsg (1, (_ T ("mapgain volume set gain = 0x % x \ n"), gain); // lqm test.

If (m_secondarygainclass <secondarydevicegainclassmax)
{
// Apply device gain
DWORD devicegain = m_pdevicecontext-> getgain () & 0 xFFFF;
Retailmsg (1, (_ T ("Gain = 0x % x, devicegain = 0x % x \ n"), gain, devicegain); // lqm test.
Totalgain * = devicegain;
Totalgain + = 0 xFFFF; // round up
Totalgain> = 16; // shift to lowest 16 bits
}

// Apply secondary gain
Totalgain * = secondarygain;
Totalgain + = 0 xFFFF; // round up
Totalgain> = 16; // shift to lowest 16 bits

Retailmsg (1, (_ T ("mapgain volume set totalgain = 0x % x \ n"), totalgain); // lqm test.

// Special Case 0 as totally muted
If (totalgain = 0)
{
Return 0;
}

// Convert to index into table
DWORD Index = 63-(totalgain> 10 );
Retailmsg (1, (_ T ("mapgain Index = 0x % x \ n"), index); // lqm test.
// Index = 50; // lqm added for test.10-05-06
Return gainmap [Index];
}
The input parameter gain is the m_dwgain mentioned above. this parameter is a 32-bit register and stores the left and right channels respectively for the high 16-bit and low 16-bit registers. Generally, the volume of the left and right audio channels is the same, so the program only takes 16 lower bits.
Totalgain is the product of devicegain and m_dwgain, which is obtained by moving 16 bits to the right. It is actually totalgain = devicegain * m_dwgain/the highest volume. If you calculate the devicegain/highest volume by percentage, it is easier to understand, the formula is totalgain = devicegain * system volume percentage. This explains how the system volume limits the volume.
Finally, an index is used to obtain the corresponding volume weight, and then the volume is set through the volume table. You can see that index = 63-(totalgain> 10); index is in the range of 0 to 63. The returned gainmap table is as follows:
Const DWORD gainmap [] =
{
0x10000, // 0: 0.000000 DB
0xec77, // 1:-1.587302 DB
0xda6d, // 2:-3.174603 DB
0xc9c2, // 3:-4.761905 DB
0xba5d, // 4:-6.349206 DB
0xac25, // 5:-7.936508 DB
0x9f03, // 6:-9.523810 DB
0x92e1, // 7:-11.111111 DB
0x87ac, // 8:-12.698413 DB
0x7d52, // 9:-14.285714 DB
0x73c2, // 10:-15.873016 DB
0x6aed, // 11:-17.460317 DB
0x62c5, // 12:-19.047619 DB
0x5b3b, // 13:-20.634921 DB
0x5445, // 14:-22.222222 DB
0x4dd7, // 15:-23.809524 DB
0x47e7, // 16:-25.396825 DB
0x0000b, // 17:-26.984127 DB
0x3d59, // 18:-28.571429 DB
0x38ab, // 19:-30.158730 DB
0x3458, // 20:-31.746032 DB
0x305a, // 21:-33.333333 DB
0x2ca9, // 22:-34.920635 DB
0x2941, // 23:-36.507937 DB
0x261b, // 24:-38.095238 DB
0x2333, // 25:-39.682540 DB
0x2083, // 26:-41.269841 DB
0x1e08, // 27:-42.857143 DB
0x1bbe, // 28:-44.444444 DB
0x19a0, // 29:-46.031746 DB
0x17ab, // 30:-47.619048 DB
0x15dd, // 31:-49.206349 DB
0x1432, // 32:-50.793651 DB
0x12a7, // 33:-52.380952 DB
0x113b, // 34:-53.968254 DB
0x0fea, // 35:-55.555556 DB
0x0eb3, // 36:-57.142857 DB
0x0d94, // 37:-58.730159 DB
0x0c8b, // 38:-60.317460 DB
0x0b96, // 39:-61.904762 DB
0x0ab4, // 40:-63.492063 DB
0x09e3, // 41:-65.079365 DB
0x0921, // 42:-66.666667 DB
0x086f, // 43:-68.253968 DB
0x07ca, // 44:-69.841270 DB
0x0732, // 45:-71.428571 DB
0x06a6, // 46:-73.015873 DB
0x0624, // 47:-74.603175 DB
0x05ac, // 48:-76.190476 DB
0x053d, // 49:-77.777778 DB
0x04d7, // 50:-79.365079 DB
0x0478, // 51:-80.952381 DB
0x0421, // 52:-82.539683 DB
0x03d0, // 53:-84.126984 DB
0x0386, // 54:-85.714286 DB
0x0341, // 55:-87.301587 DB
0x0301, // 56:-88.888889 DB
0x02c6, // 57:-90.476190 DB
0x0290, // 58:-92.063492 DB
0x025e, // 59:-93.650794 DB
0x0230, // 60:-95.238095 DB
0x0205, // 61:-96.825397 DB
0x01de, // 62:-98.412698 DB
0x01b9, // 63:-100.000000 DB
};
This is the volume configuration table that is finally called by soft volume settings. Specifically, how does one use this table to set the soft volume? Do I need to carefully study whether the digital signal sent from I2S to the audio chip contains the volume data? However, here, the soft volume adjustment function has been implemented, and the detailed principle will be carefully studied if there is no time.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.