Capturing Sound output - c#

What I need to do is to get the audio stream playing on my speakers, without any additional hardware.
If there is a speakers output (say a human voice) then I need to display some images. So How can i determine whether there is a sound coming out of the speakers??
I want to use C# for this on windows 7.
Thank you.

You can do this with WASAPI Loopback Capture. My open source NAudio library includes a wrapper for this called WasapiLoopbackCapture. One quirk of WASAPI Loopback Capture is that you get no callbacks whatsoever when the system is playing silence, although that might not matter for you
If you don't actually need to examine the values of the samples, WASAPI also allows you to monitor the volume level of a device. In NAudio you can access this with AudioMeterInformation or AudioEndpointVolume on the MMDevice (you can get this with MMDeviceEnumerator.GetDefaultAudioEndpoint for rendering)

You can use CSCore which allows you to get the peak of any applications and of the whole device. You can determine whether sound is getting played by checking that peak value. This is an example on how to get the peak of an application. And these are two examples how to get the peak of one particular device:
[TestMethod]
[TestCategory("CoreAudioAPI.Endpoint")]
public void CanGetAudioMeterInformationPeakValue()
{
using (var device = Utils.GetDefaultRenderDevice())
using (var meter = AudioMeterInformation.FromDevice(device))
{
Console.WriteLine(meter.PeakValue);
}
}
[TestMethod]
[TestCategory("CoreAudioAPI.Endpoint")]
public void CanGetAudioMeterInformationChannelsPeaks()
{
using (var device = Utils.GetDefaultRenderDevice())
using (var meter = AudioMeterInformation.FromDevice(device))
{
for (int i = 0; i < meter.MeteringChannelCount; i++)
{
Console.WriteLine(meter[i]);
}
}
}
Just check whether there is a peak bigger than zero or something like 0.05 (you may need to experiment with that). If the peak is bigger than a certain value, there is any application playing something.
Also take a look at this: http://cscore.codeplex.com/SourceControl/latest#CSCore.Test/CoreAudioAPI/EndpointTests.cs. To get get implementation of Utils.GetDefaultRendererDevice see take a look at this one: http://cscore.codeplex.com/SourceControl/latest#CSCore.Test/CoreAudioAPI/Utils.cs
The first example gets the average peak of all channel peaks and the second example gets the peaks of each channel of the output device.

Related

Is there a way to get a speaker to talk using a TinyCLR program?

I'm setting up a system using the GHI Electronics FEZ board(like an Arduino). I have created a way to send a frequency to a speaker and create a tone. Which allowed me to make music. Yet I can not figure out how to create tones that get a speaker to "talk" in a sense.
I have tried a text to speech nuget package that already exists yet it would not allow me to install it within the TinyCLR programming I am using.
C# using a Pulse Width Modulation controller I can control the desired frequency
public static PwmController fezPWM = PwmController.FromName(FEZ.PwmChannel.Controller3.Id);
static PwmChannel MusicSound = fezPWM.OpenChannel(FEZ.PwmChannel.Controller3.D11);
MusicSound.Start();
fezPWM.SetDesiredFrequency(F4s);
MusicSound.Stop();
The above part allows me to start and stop the sound and setting it to any desired frequency.
I expect it to use of desired frequencies in context to create a word. Yet all I get are different tones.

Android(Xamarin) How to get data(pulse) from the bracelet via Bluetooth

My goal is to get data (pulse) from the fitness bracelet Torntisc T1 using my application and independently process data from the bracelet.
To implement I use Xamarin and found a Bluetooth LE plugin for Xamarin plugin to connect to the device and receive data from it. However, all the characteristics obtained are called "Unknown characteristic" and in values ​​of 0 bytes. Although it has 5 services, each of which has 3 characteristics. The only name of characteristics in 1 service is other: "Device Name", "Appearance", "Peripheral Preferred Connection Parameters". However, the value (value) is everywhere 0 bytes. How to get characteristics? How to get a pulse?
To the bracelet there is an application H Band 2.0, which shows a fairly large number of settings for the bracelet, the question arises where is all this?
Native app H Band 2.0. Attempt of decompile here. I found the classes responsible for the connection in the following directory: sources\no\nordicsemi\android\dfu. I see what has been done via BluetoothGatt. Unfortunately I am not an expert in java and android, unfamiliar with this library. I didn't find any methods or anything related to the "pulse", but a large number of magic parsing characteristics: parse (characteristic)
foreach (var TestService in Services)
{
var characteristics = await TestService.GetCharacteristicsAsync();
foreach (var Characteristic in characteristics)
{
var properties = Characteristic.Properties;
var name = Characteristic.Name;
var serv = Characteristic.Service;
var value = Characteristic.Value;
var stringValue = value.ToString();
string result = "";
if (value.Length != 0)
result = System.Text.Encoding.UTF8.GetString(value, 0, value.Length - 1);
}
}
To start with you can use the following app to get a better overview of the services and characteristics you are working with, without having to code calls to get the values you need.
Having said that you will need documentation to be able to communicate with the device, what I mean is what data you send, what are acceptable responses how they map to meaningful data etc. The core of BLE is the low energy bit which means exchange as little data as possible ex. mapping integers to enum values which you do not know without the documentation, you can work your way back from decompiled source but it will be orders of magnitude more difficult.
One more thing is that BLE is notoriously unreliable (you will understand if you run into gatt 133 errros on samsungs :), so most implementations also have a sort of added network layer to handle drops and graceful degradation, as well as sending larger peaces of data, this is custom developed per app/device and you also need extensive documentation for this to implement it, which is no trivial matter.
The library you've chosen is quite good and wraps most things you need quite well but it does not handle the instability so you have to take care of that part yourself.
Cheers :)

Unity with Neurosky - Port scanning

I have this C# script on Unity to scan available serial ports to connect to Neurosky. However, this is a manual detection, this just works on computers whose Starting port of ThinkGear Connector is COM9.
void setupNeuro() {
tgHandleId = ThinkGear.TG_GetNewConnectionId();
tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId,
"\\\\.\\COM9",
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
}
How to edit this C# script to automatically detect a right port from COM1 to COMxx ?
This isn't a Unity problem as much as it is a C# one. The ThinkGear docs mention that users should implement port scanning, but I don't recall there being any implementation provided, although the suggestion of storing the previous port is provided.
Unfortunately, there are no truly elegant ways to implement this, but there are ways.
The best you can do is looping through the ports until you get one that doesn't timeout, but this means each check needs to take at least 2 seconds. And to make matters worse, the only method you have to get connected Serial Ports from .NET in Unity isn't guaranteed to be up to date either. This means you might end up enumerating over a ton of serial ports in a really slow manner.
To minimize search times you should search in this order:
Last port that was used (Store this in PlayerPrefs)
All ports returned by SerialPort.GetPortNames. There won't be many, but unfortunately, there's no guarantee they all exist, since, as the docs say, SerialPort.GetPortNames checks a registry value that is not always up to date.
Ports 0-10 if you haven't already checked them.
Ports 10 - 256, but see below. At this point you'll have to at least give the user a chance to enter the port themselves, or give them a warning about how long the next step will take.
I wouldn't recommend going this far (does up to 8 minutes of searching sound reasonable?). You'll already have spent up to 20 seconds scanning the first 10 ports. It might be worth it to
Show users how to find the right port themselves
Write a small external program for each platform that uses lower level methods to display the right port for the user to enter.
Access those lower level methods from a OS-specific library and access it from Unity to limit your search to valid ports. This is the choice I'd go with.
Checking a port goes something like this (the lambda is needed because of the use of a coroutine):
IEnumerable AttemptHeadsetConnection(int portNumber,Action<int,int> headsetConnectedCallback, Action attemptCompletedCallback)
{
var connectionString = string.Format("\\\\.\\COM{0}",portNumber);//That string literal should be elsewhere
return AttemptHeadsetConnection(connectionString, headsetConnectedCallback, attemptCompletedCallback);
}
IEnumerable AttemptHeadsetConnection(string connectionString,Action<int,int> headsetConnectedCallback,Action attemptCompletedCallback)
{
connectionID = ThinkGear.TG_GetNewConnectionId();
connectionStatus = ThinkGear.TG_Connect(connectionID ,
connectionString,
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
if(connectStatus >= 0)
{
yield return new WaitForSeconds(2f); //Give the headset at least 2 seconds to respond with valid data
int receivedPackets = ThinkGear.TG_ReadPackets(handleID, -1);//Read all the packets with -1
if(receivedPackets > 0)
{
headsetConnectedCallback(connectionID,connectionStatus);
}
else
{
ThinkGear.TG_FreeConnection(handleID);
}
}
attemptCompletedCallback();
}
And use that with something like:
foreach(var serialPort in SerialPort.GetPortNames())
{
var connectionCoroutine = AttemptHeadsetConnection(serialPort,onFoundHeadset,onAttemptCompleted);
StartCoroutine(connectionCoroutine);
}
Note about the code: It's not elegant, and it might not even compile (although it doesn't do anything that's impossible). Take it as very convincing psuedo-code and use it as your base.
loop thru the known ports substituting the COM number into the connect string until you either run out of ports (nothing connected) or find one that is...

C# get max resolution on winpe, without any drivers

Im looking for a way to get the maximum supported screen resolution.
I need to find this without any drivers installed.
I have already tried using WMI and the EnumDisplaySettings.
Is it possible to get this information direct from the hardware, or do i need to look it up online? If online, which information do i then need in order to look it up?
EnumDisplaySettings give you all the screen resolutions in a loop. It is up to you to choose which one is the "maximum" (the widest or the tallest?)
I've done it, in C++ :
for (i=0;; i++)
{
memset(&vimodetmp,0,sizeof vimodetmp);
vimodetmp.dmSize = sizeof vimodetmp;
if (!EnumDisplaySettings(DisplayDevice.DeviceName,i,&vimodetmp))
{
break;
}
// store in a array
}
// you can choose in the array
Hope that can help you.

How to configure DirectSound's MaxSampleRate above 20000

I'm programming small program to output generated sound.
My sound card is capable of a 48000 or even 192000 sample rate. Its a Realtek ALC883 7.1+2 Channel High Definition Audio, and the specs can be found here.
However, DirectSound's MaxSampleRate has a maximum value of 20000?
I know I can get better than the maximum from my sound card, but how do I configure DirectSound to take advantage of this? When I try the following:
DirectSound ds = new DirectSound(DirectSound.GetDevices().First().DriverGuid);
MessageBox.Show(ds.Capabilities
.MaxSecondarySampleRate
.ToString(CultureInfo.InvariantCulture));
In message box the number displayed is "20000".
It could be that your sound card is not the first device in the devices list (for example, a video card with a tv outpout would appear in the list). You should look at the DeviceInformation.Description property. Otherwise, maybe a problem with the driver ?

Categories