C# Get Audio Volume For Each Speaker In 7.1 Audio - c#

Today I was trying to make simple C# application to display real-time volume of system sound. I have success with NAudio library using this code:
var enumerator = new MMDeviceEnumerator();
var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
while (true)
{
Console.Write("\r{0}", device.AudioMeterInformation.MasterPeakValue);
}
// Output: 0,2314617
The problem is that I want to get audio volume of each speaker of my 7.1 audio system instead of master volume, so the output will look like:
Speaker1: 0,435462
Speaker2: 0,237462
Speaker3: 0,535962
Speaker4: 0,335862
Speaker5: 0,835462
Speaker6: 0,635462
Speaker7: 0,335462
Subwoofer: 0,236562
Is there any way I can do it? If there is a way can you provide an example?

Based on Roman R. comment I figured out this solution:
var enumerator = new MMDeviceEnumerator();
var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
while (true)
{
for (int i = 0;i< device.AudioMeterInformation.PeakValues.Count;i++)
{
Console.WriteLine("ID: " + i + " : " + device.AudioMeterInformation.PeakValues[i]);
}
}

Related

C# How can I get the masterpeek value from a specific application with Naudio

I'm fairly new to C#. In my program, I can measure the masterpeek value of the computer. But what I need right now is only the masterpeek value of a particular application, rather than the masterpeek value of the computer. For example chrome.exe masterpeek value.
I'm importing audio output devices into ComboBox.
var deviceEnum = new MMDeviceEnumerator();
var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
foreach (var dev in devices)
{
comboDevices.Items.Add(dev.FriendlyName);
}
comboDevices.SelectedIndex = 0;
deviceEnum.Dispose();
I choose the output device.
using (MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator())
{
var deviceList = deviceEnum.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).ToList();
device = deviceList[comboDevices.SelectedIndex];
}
I can show the masterpeek value with the progressbar.
if (comboDevices.SelectedItem != null)
{
var mpValue = Math.Round(device.AudioMeterInformation.MasterPeakValue * 100);
progressAudioMeter.Value = Convert.ToInt32(mpValue);
}
But now what I want to do exactly is the volume value of a particular application instead of the total volume value. For example chrome.exe
An example image from the audio mixer
I did some research and couldn't find exactly what I wanted. Can you help me? I don't know how I can do this.

USB Printing for DOT Matrix POS printer

I was trying to print to an usb printer using usbmanager, the App can detect the printer device but when i run it doesnt print. there are no errors and all passing data is ok.
Printer : Bixolon SRP 275III
Type: USB
private async void printReciept()
{
UsbManager m_usbManager;
m_usbManager = (UsbManager)Application.Context.GetSystemService(Context.UsbService);
var deviceList = m_usbManager.DeviceList;
IEnumerable<UsbDevice> deviceIterator = deviceList.Values.AsEnumerable();
UsbDevice m_usbdevice = null;
if (deviceIterator.Count() > 0)
{
var device = deviceIterator.ElementAt(0);
m_usbdevice = device;
string ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
var mPermissionIntent = PendingIntent.GetBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
m_usbManager.RequestPermission(m_usbdevice, mPermissionIntent);
UsbDeviceConnection deviceConnection = null;
try
{
using (var usbInterface = m_usbdevice.GetInterface(0))
{
using (var usbEndpoint = usbInterface.GetEndpoint(0))
{
mEndPoint = usbEndpoint;
deviceConnection = m_usbManager.OpenDevice(m_usbdevice);
byte[] bytesHello = Encoding.UTF8.GetBytes("Hello");
deviceConnection.BulkTransfer(usbEndpoint, bytesHello, bytesHello.Length, 0);
}
}
}
catch
{
}
}
}
You are sending the string to be printed directly to the bulk endpoint, or actually you are doing bulk transfer to the first endpoint found without knowing any of it's characteristics? I think it is a bit more complex than that.
First try to find out whether your printer supports USB printing class or some proprietary implementation. You can do this easily e.g. by connecting the printer to Windows PC and looking from the device manager, usbdeview or some other similar application.
If it supports printing class, read this document and implement your driver based on that (or use the one you may already have in Android). If it only supports proprietary implementation, you need to get the specifications for it or do some reverse engineering.
You may need to learn about PCL which may also be needed.

C# get portable devices connected to PC

I am trying to get all usb devices(including portable devices) on Windows 7
now I searched all over and didnt find a good answer.
I tried this code:
static void Main(string[] args)
{
//
// Get an instance of the device manager
//
PortableDeviceApiLib.PortableDeviceManagerClass devMgr
= new PortableDeviceApiLib.PortableDeviceManagerClass();
//
// Probe for number of devices
//
uint cDevices = 1;
devMgr.GetDevices(null, ref cDevices);
//
// Re-allocate if needed
//
if (cDevices > 0)
{
string[] deviceIDs = new string[cDevices];
devMgr.GetDevices(deviceIDs, ref cDevices);
for (int ndxDevices = 0; ndxDevices < cDevices; ndxDevices++)
{
Console.WriteLine("Device[{0}]: {1}",
ndxDevices + 1, deviceIDs[ndxDevices]);
}
}
else
{
Console.WriteLine("No WPD devices are present!");
}
}
but i get this error:
interop type 'portabledeviceapilib.portabledevicemanagerclass' Cannot
be embedded
Now im pretty stuck.
If you could help me with this code/ give me an idea what should i try, ill be happy
all I need is to get which type of USB got connected,
if a phone is connected, or a mouse. i want to know what is connected.
Thanx Ahead
I am using the NuGet package PortableDevices (which is based on the tutorial by Christophe Geers).
Derived from part one of the tutorial:
public void ListDevices()
{
var devices = new PortableDeviceCollection();
devices.Refresh();
foreach (var device in devices)
{
device.Connect();
Console.WriteLine(#"DeviceId: {0}, FriendlyName: {1}", device.DeviceId, device.FriendlyName);
device.Disconnect();
}
}
To expand on #CodeFox's answer, and in order to make his code ListDevices() work:
Download the NuGet package PortableDevices
Add references to these 4 COM libraries:
PortableDeviceClassExtension
PortableDeviceConnectApi
PortableDeviceTypes
PortableDeviceApi
Take the dll's under obj\Debug and put them into bin\Debug:
Interop.PortableDeviceClassExtension.dll
Interop.PortableDeviceConnectApiLib.dll
Interop.PortableDeviceTypesLib.dll
Interop.PortableDeviceApiLib.dll
Now you can use this function, although FriendlyName does not seem to be working (it returns an empty string):
private IDictionary<string, string> GetDeviceIds()
{
var deviceIds = new Dictionary<string, string>();
var devices = new PortableDeviceCollection();
devices.Refresh();
foreach (var device in devices)
{
device.Connect();
deviceIds.Add(device.FriendlyName, device.DeviceId);
Console.WriteLine(#"DeviceId: {0}, FriendlyName: {1}", device.DeviceId, device.FriendlyName);
device.Disconnect();
}
return deviceIds;
}
The next step for me is getting the contents from the device, which is done like so:
var contents = device.GetContents();

Play audio at two different Audiodevices simultaneously with Naudio

My question is similar to one here :
Play audio to two different Audiodevices simultaneously with Naudio
But i ask it here again since it has not been answered clearly in the link above.
I also have it at:
Play sound in both speaker and headset wpf
Inspiration from :
Play a sound in a specific device with C#
I am adding source code and adding the NAudio tag here as well.
I have an wpf application and i am using the soundPlayer class to play sound (for eg ringtone). Currently the tone plays either on speakers or on the headset (if its plugged in). I would like the application to play the tone on speaker even when the headsets are plugged in. I know there are ways to do this in android, but couldn't find any in wpf. I would also like an UI for the user to choose the devices in which he would like to hear sound. Any help is appreciated. Thanks !
public void detectDevices()
{
int waveOutDevices = WaveOut.DeviceCount;
switch (waveOutDevices)
{
case 1:
var wave1 = new WaveOut();
wave1.DeviceNumber = 0;
playSound(0);
break;
case 2:
var wave2 = new WaveOut();
wave2.DeviceNumber = 0;
playSound(0);
var wave3 = new WaveOut();
wave3.DeviceNumber = 1;
playSound(1);
break;
}
}
public void playSound(int deviceNumber)
{
disposeWave();// stop previous sounds before starting
waveReader = new NAudio.Wave.WaveFileReader(fileName);
var waveOut = new NAudio.Wave.WaveOut();
waveOut.DeviceNumber = deviceNumber;
output = waveOut;
output.Init(waveReader);
output.Play();
}
public void disposeWave()
{
if (output != null)
{
if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing)
{
output.Stop();
output.Dispose();
output = null;
}
}
if (wave != null)
{
wave.Dispose();
wave = null;
}
}
case eSelector.startIncomingRinging:
fileName = ("Ring.wav");
detectDevices();
I still hear ringtone just in one device (either in headset or speakers) using the code above.
You need two instances of WaveOut, one for each soundcard. And then the simplest way if you are playing from file, is to also have two instances of WaveFileReader. You can't easily synchronize them I'm afraid, you'll just have to start them both playing together and hope for the best.
The wave1, wave2 and wave3 classes in your code above do abosolutely nothing. The audio will be played with the WaveOut device you create in playSound. You seem to have a single class property called output and another called waveReader, when you need two of each.

Taking input from a joystick with C# .NET

I searched around on Google for this, but the only things I came up with were outdated and did not work.
Does anyone have any information on how to get joystick data using C# .NET?
Since this was the top hit I got on google while researching joystick / gamepad input in C#, I thought I should post a response for others to see.
The easiest way I found was to use SharpDX and DirectInput. You can install it via NuGet (SharpDX.DirectInput)
After that, it's simply a matter of calling a few methods:
Sample code from SharpDX
static void Main()
{
// Initialize DirectInput
var directInput = new DirectInput();
// Find a Joystick Guid
var joystickGuid = Guid.Empty;
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Gamepad not found, look for a Joystick
if (joystickGuid == Guid.Empty)
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Joystick not found, throws an error
if (joystickGuid == Guid.Empty)
{
Console.WriteLine("No joystick/Gamepad found.");
Console.ReadKey();
Environment.Exit(1);
}
// Instantiate the joystick
var joystick = new Joystick(directInput, joystickGuid);
Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);
// Query all suported ForceFeedback effects
var allEffects = joystick.GetEffects();
foreach (var effectInfo in allEffects)
Console.WriteLine("Effect available {0}", effectInfo.Name);
// Set BufferSize in order to use buffered data.
joystick.Properties.BufferSize = 128;
// Acquire the joystick
joystick.Acquire();
// Poll events from joystick
while (true)
{
joystick.Poll();
var datas = joystick.GetBufferedData();
foreach (var state in datas)
Console.WriteLine(state);
}
}
I hope this helps.
I even got this to work with a DualShock3 and the MotioninJoy drivers.
One: use SlimDX.
Two: it looks something like this (where GamepadDevice is my own wrapper, and the code is slimmed down to just the relevant parts).
Find the joystick / pad GUIDs:
public virtual IList<GamepadDevice> Available()
{
IList<GamepadDevice> result = new List<GamepadDevice>();
DirectInput dinput = new DirectInput();
foreach (DeviceInstance di in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
{
GamepadDevice dev = new GamepadDevice();
dev.Guid = di.InstanceGuid;
dev.Name = di.InstanceName;
result.Add(dev);
}
return result;
}
Once the user has selected from the list, acquire the gamepad:
private void acquire(System.Windows.Forms.Form parent)
{
DirectInput dinput = new DirectInput();
pad = new Joystick(dinput, this.Device.Guid);
foreach (DeviceObjectInstance doi in pad.GetObjects(ObjectDeviceType.Axis))
{
pad.GetObjectPropertiesById((int)doi.ObjectType).SetRange(-5000, 5000);
}
pad.Properties.AxisMode = DeviceAxisMode.Absolute;
pad.SetCooperativeLevel(parent, (CooperativeLevel.Nonexclusive | CooperativeLevel.Background));
pad.Acquire();
}
Polling the pad looks like this:
JoystickState state = new JoystickState();
if (pad.Poll().IsFailure)
{
result.Disconnect = true;
return result;
}
if (pad.GetCurrentState(ref state).IsFailure)
{
result.Disconnect = true;
return result;
}
result.X = state.X / 5000.0f;
result.Y = state.Y / 5000.0f;
int ispressed = 0;
bool[] buttons = state.GetButtons();
The bad news is that Microsoft seems to stop supporting their NET libraries for DirectX and focus on XNA instead. I don't work in GameDev so I don't need to use XNA but you may try it if you developing computer games. The good news is that there are other approaches. One is SlimDX the new framework to help you to wok with DirectX from C#. The other way is to directly add references of "Microsoft.DirectX.dll" and "Microsoft.DirectX.DirectInput.dll" to your project. you can find them "..\Windows\Microsoft.NET\DirectX for Managed Code\". if you you are going to use last approach here is a link to codeproject where you can read how to work with a joystick.
EDIT:
If your application is based on NET version newer then 2.0 the application may hang on. To fix this problem change config file and add this:
<startup useLegacyV2RuntimeActivationPolicy="true">
Google led me here and while not a requirement of this question, OpenTK is a good option for Windows and Linux (under mono) support.
From the OpenTK docs, this code works on Raspberry Pi + Raspbian + Mono 3.12.0:
for (int i = 0; i < 4; i++)
{
var state = Joystick.GetState(i);
if (state.IsConnected)
{
float x = state.GetAxis(JoystickAxis.Axis0);
float y = state.GetAxis(JoystickAxis.Axis1);
// Print the current state of the joystick
Console.WriteLine(state);
}
}
This question is old, but it seems to be active even to this day, so I'm posting anyway.
If you need to get input from XInput only, take a look at XInputium. This is a .NET library that is specialized in XInput controllers. It is pretty straightforward, and has many code samples you can look at.

Categories