ALSA sound card 12_Add volume control from scratch_Study notes

Publisher:EnchantedWishLatest update time:2024-07-16 Source: elecfans Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. The process of calling the application when setting the volume

(1)strace分析: amixer cset numid=1 30 (设置音量)
/dev/snd/controlC0
open
SNDRV_CTL_IOCTL_CARD_INFO
SNDRV_CTL_IOCTL_PVERSION
SNDRV_CEL_CTL_CTL_CTL_CTL_V READ
SNDRV_CTL_IOCTL_ELEM_WRITE
: snd_ctl_elem_write_user

(2) When the application calls SNDRV_CTL_IOCTL_ELEM_WRITE, the driver calls the snd_ctl_elem_write_user function, which copies some parameters from user space and then calls the snd_ctl_elem_write function.

(3) Function snd_ctl_elem_write

Find a snd_kcontrol structure and then call the put function of the snd_control structure.


(4) Who provides this snd_kcontrol structure?

ASOC drivers are divided into three parts (machine, codec, platform). The codec part should be provided because it is closely related to the sound card. When adjusting the volume, you must adjust it.



2. Write the program (uda1341.c (codec))

(1)Structure snd_kcontrol_new

static const struct snd_kcontrol_new uda1341_vol_control =
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, //Indicates which type of device the snd_kcontrol structure is used for (indicates parameter setting)
.name = "Master Playback Volume", //Volume control. The snd_kcontrol of each sound card driver is different. Why can applications adjust its volume? For some commonly used properties, they all have fixed names. The application finds its snd_kcontrol item according to the name and calls the put function inside.
.info = uda1341_info_vol, //Get some information, such as the volume range.get
= uda1341_get_vol, //Get the current volume value.put
= uda1341_put_vol, //Set the volume
};


(2) Obtain volume information, such as minimum and maximum values

/*
* Get volume information, such as minimum and maximum values
*/
int uda1341_info_vol(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; //The type of volume value is integer
uinfo->count = 2; //The number of channels is dual-channel
uinfo->value.integer.min = 0; //Minimum integer,
uinfo->value.integer.max = 63; //Maximum integer,
return 0;
}

Because the volume control of uda1341 is 6 bits (0 means maximum volume, 63 means minimum volume), and in the application, 0 means minimum volume, and the larger the value, the higher the volume.


(3) Get the current volume value

/*
* Get the current volume value
*/
int uda1341_get_vol(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);


ucontrol->value.integer.value[1] = //Here it means ucontrol->value.integer.value[0] is equal to ucontrol->value.integer.value[1], because it is dual channel
ucontrol->value.integer.value[0] = 63 - snd_soc_read(codec, UDA1341_DATA00); //Read the value of register DAT00, because the value of the driver and the value of the application are opposite in size, uda1341 does not support register read operation, to get the value of a register, it is to read a cache (this cache saves the value of the setting register)
return 0;
}

(4) Set the current volume value

/*
* Set the current volume value
*/
int uda1341_put_vol(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int val;


val = 63 - ucontrol->value.integer.value[0];//The value passed by the application needs to be reversed when written to the register


snd_soc_write(codec, UDA1341_DATA00, val);//Write the value val to register DATA00 return

0;
}

3. Connection between structure snd_kcontrol_new and kernel part

(1) probe function

static int uda1341_soc_probe(struct snd_soc_codec *codec)
{
int ret;
uda1341_init_regs(codec);

ret = snd_soc_add_codec_controls(codec, &uda1341_vol_control, 1);
return ret;
}


4. Testing


amixer controlsView controls

amixer cget numid=1 means check the current volume

amixer cset numid=1 30 Set the volume



5、Input Mux

Because different boards have different microphone channels (in uda1341), with the same driver, the application should set the input mux option when recording.



Indicates which microphone channel it can select, which microphone channel is currently, and which microphone channel is set


The value uda134x_mixer_enum[2] is the second item in the array


6、

Let the board use the kernel's built-in driver


View the device nodes and control items (input mux is the second to last item)


View the value of control item 11 (the current value is 0)


If you select the first channel (analog channel), the last parameter indicates which channel


Reference address:ALSA sound card 12_Add volume control from scratch_Study notes

Previous article:ALSA sound card 09_parameter setting written from scratch_study notes
Next article:ALSA Sound Card 16_Writing ALSA Sound Card Application_Study Notes

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号