My audio system is simple: two speakers in the rear panel--front left(FL) ,front right(FR) ,headphone in the front panel. The primitive status is as below--primitive status:
In this status , sound can be heared from FL,FR,and headphone.
I find a strange fact that master,front,surround in alsamixer changed into MM status when to click M on LFE,i move the cursor on LFE,and click M,LFE changed into MM,at the same time master,front,surround all changed into MM status !No sound can be heared !
And i click M for the second time on LFE,all status changed as below:
Let's go on from the primitive status,and unplug line from rear panel,no sound in headphone! The status in alsamixer gui is as below:
Now re-plug the line in the rear panel,the status in alsamixer gui turns into :
Please give an explanation in detail.
To see what's going on:
In one terminal window, run alsactl monitor.
In another terminal window, run alsamixer.
As you mute/unmute things in alsamixer, you can see the control commands in the monitor window. You should see multiple switch commands show up when you mute the LFE.
The reason this is happening is because of the pulseaudio profile in use by alsamixer.
Profiles are located in /usr/share/pulseaudio/alsa-mixer/profile-sets/*.conf
Paths are located in /usr/share/pulseaudio/alsa-mixer/paths/*.conf
So which ones are in use? You can check that with pacmd info | grep "active", which may produce something like:
active port: <analog-output-speaker>
active port: <analog-input-headphone-mic>
active profile: <output:analog-stereo+input:analog-stereo>
Ok, so the output mapping is analog-stereo. I can find this in /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf. It contains the following:
[Mapping analog-stereo]
device-strings = front:%f hw:%f
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 10
The real control is under /usr/share/pulseaudio/alsa-mixer/paths/analog-output-speaker.conf. You can read /usr/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common for details, where we see two important sections:
; When a device shall be muted/unmuted *all* elements listed in a path
; file with "switch = mute" will be toggled.
(there's a bit of a caveat to this one. It seems that unmuting does NOT toggle other elements in the path)
and
; [Element ...] # For each element that we shall control
...
; switch = ignore | mute | off | on | select # What to do with this switch: ignore it, make it follow mute status,
; # always set it to off, always to on, or make it selectable as port.
; # If set to 'select' you need to define an Option section for on
; # and off
...
So now, if we want to adjust an element such that it's always on, always off, or simply ignores muting, we would set the corresponding switch= values in the Element of interest.
If you want to adjust the behavior of the headphones when activating that path (i.e. when plugging them in), change the Element values in paths/analog-output-headphones.conf
Related
I have a touch screen with events at /dev/input/event12 and /dev/input/event13. /dev/input/event12 is the main touch input, and in essence, I'd like to send instructions to the event directly to control behavior (ie, click location etc).
Tools like xdotool do not want to work because this device is being set as a second pointer (see: https://dwm.suckless.org/multi-pointer/) and the recommendation of using xinput set-cp <window> <master> does not appear to work as expected.
A solution was found using Python and Python-evdev. Using evdev you can assign the device and pass parameters within the allowed functions. In my case it is as follows:
device.write(e.EV_KEY, e.BTN_TOUCH, 1)
device.write(e.EV_KEY, e.BTN_TOUCH, 0)
device.write(e.EV_SYN, 0, 0)
We have a Linux device which has a speaker and MIC devices. These devices are shared among different modules - example a VOIP call can use speaker, a hazard Warning system can use speaker, a Voice prompt can use a speaker etc:
There seems to be a function in ALSA which uses pcm to provide the status.
int snd_pcm_status (snd_pcm_t * pcm, snd_pcm_status_t * status)
However the *pcm is returned by snd_pcm_open. We do not want to open the device as we would like to know the status of the device using its "name"
Alsa API is here
How can we check if a resource/device is busy without opening it and using its name?
The same information for playback stream X of device Y on card Z is available in the file /proc/asound/cardZ/pcmYp/subX/status; when the device is not open, it just says "closed".
Please note that you cannot use this information to decide if you can open the device, because some other process could have openend it just after you've read this information. The only way to check if you can open it is to actually try.
Though it requires /dev/dsp, this seems to work:
#!/bin/dash
## If the speaker is not used by any, returns 0, and prints "free"
## Otherwise, returns 1 and prints "not free"
iExit (){
trap '' 0
exit $1
}
iCatch (){
# The speaker is already in use
echo not free
iExit 1
}
trap iCatch 0
{
exec 3>&1 1>/dev/dsp
# If the execution reaches here, the speaker is not used by any
# Otherwise, it's catched by iCatch
exec 1>&3
echo free
iExit 0
} 2>/dev/null
Without PulseAudio, it seems on some PC only one output is accepted at one time; on others simultaneous playbacks are allowed. But even in the latter case, the above code works.
NB: The above code does not work with bash; for bash, simply use if/else rather than trap.
NB 2: /dev/dsp may be lacking depending on the kernel configuration.
I've been googling for quite a long time and I just can't find any information on how to get screen_number for every screen connected to computer. Here I found a list of macros and some of them (like for example ScreenOfDisplay(display, screen_number) ) use argument screen_number. However there is no such macro that could give me a list of those numbers (one for every connected screen). I know how to get number of default screen (DefaultScreen() ) and count of all screens ( ScreenCount() ) but what about other screens? I noticed that screen_number of default screen is 0, although I have only one screen connected to my computer so I can't really test what happens when there are more of them. I think that screen_number could be assigned in a very simple way which is screen_number=0 for first screen,screen_number=1 for second,screen_number=2 for third and so on but as I said... I can't test wheather it's true and even if I had multiple screens how could I be sure that it works like this for all computers .Please ,if anyone of you has more experience with X11 and knows all details about how it works,tell me if I am right.
The ScreenCount(dpy) macro and int XScreenCount(Display*) function both return the number of screens connected to the display. Valid screen numbers are 0 to ScreenCount(dpy)-1. Macros in Xlib.h confirm:
#define ScreenCount(dpy) (((_XPrivDisplay)dpy)->nscreens)
#define ScreenOfDisplay(dpy, scr) (&((_XPrivDisplay)dpy)->screens[scr])
Your source (2.2.1. Display Macros) provides enough information. Normally the default screen-number is 0, e.g., when connecting to the local host you could use :0.0 as indicated in the documentation for XOpenDisplay.
That is "normally". If you run VNC, normally that runs on a different display (the first 0 in the simple connection string shown).
But (reading the documentation), when an application calls XOpenDisplay, it asks for the given screen-number (which the X server may/may not honor):
screen_number
Specifies the screen to be used on that server. Multiple screens can be controlled by a single X server. The screen_number sets an internal variable that can be accessed by using the DefaultScreen() macro or the XDefaultScreen() function if you are using languages other than C (see "Display Macros").
The man page is here: http://man.cat-v.org/unix-6th/3/ttyn
This example:
if (ttyn(0) = 'x'){
...
}
The man page says "x is returned if the indicated file does not correspond to a
typewriter."
The indicated file would be argument 0, so the standardinput, right?
And what is a typewriter? My keyboard?
What are you checking with this line?
if (ttyn(0) = 'x')
At that point in time, a typewriter (or teletype, or tty) was an RS-232 terminal connected to the computer via a serial port. The device entries in /dev corresponding to these ports were named /dev/tty0, /dev/tty1, /dev/ttya, etc. Each of those files was a character special file, as opposed to an ordinary file.
When a terminal was detected by the system, typically by being turned on or connected through a modem, the init process opened the device on file descriptors 0, 1, and 2 in a new process, and those file descriptors persisted through the login process, a user's shell, and any processes forked from the shell.
As you said in your question, file descriptor 0 is also called standard input.
The ttyn function calls fstat on its argument, which returns some info about the file such as its inode number, permissions, etc. ttyn then reads through /dev, looking at each file that starts with "tty", to see which one has the same inode number as ttyn's argument. When it finds a match, it returns the 4th character of the filename, which would be '0', '1', 'a', etc. If no matches are found, it returns 'x'.
There were generally a console and a few 8-port serial interfaces on a PDP-11. so there was no ttyx. And you could name devices in /dev anything you wanted. So it was easy to avoid /dev/ttyx being an actual device.
Commands like goto could use ttyn(0) != 'x' to determine whether the user was actually typing the command on a terminal.
Here is the default config file, /etc/ttys, used by init in V6. The console was tty8.
In V7 Unix, the functionality of ttyn was replaced by ttyname, which could accommodate longer device names, and isatty, which returned true if the fle descriptor was a terminal device. The goto command was not present in V7.
I've never seen this library call before; I'm used to the more familiar ttyname. The webpage doesn't give a return value, but based on what the text says, it would give the last char value in the string returned by ttynam(3). So if stdin (fd0) was connected to "/dev/tty2", then the return value would be the char 2. And in C, you would be able to check it with:
if (ttyn(0) == '2') { ... }
Granted the documentation is not clear. And it is using bad terminology; instead of "typewriter", it should be using "teletype" or "terminal", which are the accepted terms. Remember that stdin can be different from stdout; it is perfectly possible to do run cat </dev/tty1 > /dev/tty2, assuming you have the permissions for it.
I've got my computer(Windows 7) hooked up to the TV, and i very often change output device for sound between Digital Audio (S/PDIF)(High definition audio device) and my headset (2- Corsair CA-HS1 USB Headset)
I wanna be able to execute a batch/script file who changes this for me so i don't have to "right click volume > playback devices > "Mark output device" and click "set default".
I know it's a luxury problem, but hey, maybe I can learn something from someone?
All help appreciated!
This is how I set 'Line 1' as the playback device:
start /min "" G:\......\nircmd.exe setdefaultsounddevice "Line 1"
NirCmd is a small command-line utility which you can download that allows you to do some useful tasks without displaying any user interface.
I had the exact same requirement as yourself, and AFTER stumbling across your posting I found the following:
https://web.archive.org/web/20131231034118/http://downloadsquad.switched.com/2010/06/16/windows-7-tip-how-to-change-the-default-audio-device-with-a-hot/
Unfortunately it's not a native Windows function; it requires the download of a small open-source scripting tool called AutoHotKey, but it works nicely and only requires a small amount of memory (1 ~ 2.5Mb)
The script provided in the original article doesn't work for me. It's searching for Enabled/Disabled devices and changing that value, as opposed to changing the default device.
I've edited it to switch between 2 default devices now.
It works by opening your Sound control panel (mmsys.cpl), then scrolling down the list of playback devices to the second item in the list (that's the {Down 2} part).
This is because my Speakers are the second item in my list.
It then checks to see if the device is default or not. If not, it sets it as the default and closes the window. If it's already the default, it scrolls down another 2 times and sets that as the default.
So, you'll need to ammend the {Down 2} lines to fit your own list of devices.
#+a::
Run, mmsys.cpl
WinWait,Sound
ControlSend,SysListView321,{Down 2}
ControlGet, selectedDevice, List, Focused, SysListView321
Loop, Parse, selectedDevice, %A_Tab%
if a_index <> 3
continue
else
{
if A_LoopField <> Default Device
{
ControlClick,&Set Default
ControlClick,OK
WinWaitClose
SoundPlay, *-1
return
}
else
{
ControlSend,SysListView321,{Down 2}
ControlClick,&Set Default
ControlClick,OK
WinWaitClose
SoundPlay, *-1
return
}
}
To follow up on Dale Newton's post, NirCmd is a great way to do this. On top of that if you pair it with AutoHotKey you can create an executable that will change your devices without opening pesky CMD windows every time you run it. For example, I have two sources that I switch between all the time, one is my headphones and they other is my monitor. For my monitor I created an ahk script that does this:
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir% ;I have nircmd in the same folder as these scripts
Run, nircmd setdefaultsounddevice "Acer X34-8" 1
Run, nircmd setdefaultsounddevice "Acer X34-8" 2
And another for my headphones with the last two lines changed to:
Run, nircmd setdefaultsounddevice "Headset Earphone" 1
Run, nircmd setdefaultsounddevice "Headset Earphone" 2
Afterwards you can compile each ahk script into an exe and bind each exe to a keyboard macro so you can execute them with a couple key presses. Personally I am using a Corsair K95 so I use their software to bind these to my 'G' keys.
Also to note, if you are in your sound preferences you can rename any of the devices to avoid naming conflicts.
I had a HDMI device that keeps changing it's name, so none of the existing solutions worked for me.
I eventually ended up with this powershell and use of the NirCmd app.
#File: TV.ps1
$name = "SMART*"
# list active audio playback devices. (Note for cature devices change Render to Capture)
$device = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\*\" | where {$_."DeviceState" -eq 1} | foreach-object -Process {(Get-ItemPropertyValue -Path ($_.PSPath + "\Properties\") -Name "{a45c254e-df1c-4efd-8020-67d146a850e0},2")} | Where-Object {$_ -like $name}
C:\bin\NIRCMDC setdefaultsounddevice $device 1
C:\bin\NIRCMDC setdefaultsounddevice $device 2
As far as I understand there is no way to do this programmatically. This is a deliberate design, since Microsoft does not want applications to override audio setting set by user.
You will find same answer here but if you solutions that manipulate windows you can have a look here.
The following script is written in Windows 7 and uses sendkeys. It is based on other snippets I found but adds to them to ensure selection is consistent and stray windows are not left displayed.
You may want to adjust SleepTime for your system if it still plays up.
Call the script using a shortcut with the index of the item you wish to select in the Playback Devices window as first parameter.
You can create a new 'toolbar' on your 'taskbar' to select each device with a single click:
Taskbar toolbar picture
'===============================================================================
'This script uses sendkeys to select the Sound Output device
'First parameter should be the desired device number in 'Playback Devices' list
'===============================================================================
Option Explicit
Const SleepTime = 200
Dim WindSh
'===============================================================================
'MAIN ROTUINE
'===============================================================================
'Check the command line input
if ( Wscript.Arguments.Count <> 1) then
MsgBox "You must provide a single integer argument representing the device number", vbinformation + vbokonly, Wscript.ScriptName
Wscript.Quit 1
elseif ( false = IsNumeric( Wscript.Arguments.Item(0) ) ) then
MsgBox "The argument provided was not an integer number: " & Wscript.Arguments.Item(0), vbinformation + vbokonly, Wscript.ScriptName
Wscript.Quit 2
End If
set WindSh = CreateObject("Wscript.Shell")
WindSh.run("control.exe mmsys.cpl")
do while (WindSh.AppActivate("Sound") = false)
WScript.Sleep SleepTime
loop
WindSh.sendkeys("{DOWN " & Clng( Wscript.Arguments.Item(0) ) & "}")
WScript.Sleep SleepTime
WindSh.sendkeys("{TAB 2}")
WScript.Sleep SleepTime
WindSh.sendkeys("{ENTER}")
WScript.Sleep SleepTime
WindSh.sendkeys("%{F4}")
WScript.Sleep SleepTime
if (WindSh.AppActivate("Sound") = true) then
WindSh.sendkeys("%{F4}")
end if
Might not be related to switching the audio device around via script, but I also have my computer hooked up to my TV via HDMI.
When I want to watch video files on the TV I use Media Player Classic Home Cinema - this lets me specify the audio device for MPH:HC in the options without switching over my default sound device on the entire computer.
If your usage is similar to mine maybe MPC:HC will solve your problem for you.
Note that if you use nircmd setdefaultsounddevice speakers in an enterprise or educational environment login script, the sound will still come out from the speakers when headphones are plugged in.