Audio Capture is not working as expected - c#

In my Microsoft Surface application I'd like to use voice capture. So I followed the tutorial metioned here (http://opensebj.blogspot.com/2009/04/naudio-tutorial-5-recording-audio.html) and modified the NAudio.dll to be able to execute the following code:
class AudioRecording
{
private WaveMixerStream32 mixer;
public AudioRecording()
{
mixer = new WaveMixerStream32();
mixer.AutoStop = false;
}
public void start()
{
Console.WriteLine("Start recording");
mixer.StreamMixToDisk("Test.wav");
mixer.StartStreamingToDisk();
}
public void stop()
{
Console.WriteLine("Stop recording");
mixer.StopStreamingToDisk();
}
}
But this doesn't really capture the sound. I just create a file of 58 bytes, that is empty. What Am I doing wrong?

Problem is sovled here:
http://naudio.codeplex.com/Thread/View.aspx?ThreadId=239825

Related

How to set up event handling with prebuild class

I am very new to C# and try to use Microsoft.MixedReality.QR for reading some QRCodes with the Hololense 2 and have problems accessing the events of the QRCodeWatcher. According to the API, the QRCodeWatcher class has 4 events but it seems that these are never triggered. (QR_Added, QR_Updated,... are never called). Am I setting up something wrong?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.QR;
using QRTracking;
namespace QRTracking {
public class Detector: MonoBehaviour {
public TextMesh debugScreen;
public bool IsSupported {get; private set; }
private QRCodeWatcher qrTracker;
private bool QRstarted=false;
private QRCodeWatcherAccessStatus accessStatus;
// Start is called before the first frame update
async protected virtual void Start() {
debugScreen.text="Hello";
if (QRCodeWatcher.IsSupported()) {
try {
accessStatus=await QRCodeWatcher.RequestAccessAsync();
debugScreen.text=accessStatus.ToString();
}
catch {
debugScreen.text="No World";
}
}
}
// Update is called once per frame
void Update() {
if (accessStatus.ToString()=="Allowed") {
if (QRstarted==false) {
debugScreen.text="Setup Tracking";
SetupQRTracking();
QRstarted=true;
}
}
}
private void SetupQRTracking() {
qrTracker=new QRCodeWatcher();
qrTracker.Added+=QR_Added;
qrTracker.Updated+=QR_Updated;
qrTracker.Removed+=QR_Removed;
qrTracker.EnumerationCompleted+=QR_Enum;
qrTracker.Start();
debugScreen.text="Tracking started";
}
private void QR_Added(object sender, QRCodeAddedEventArgs args) {
debugScreen.text="Added";
}
private void QR_Updated(object sender, QRCodeUpdatedEventArgs args) {
debugScreen.text="Updated";
}
private void QR_Removed(object sender, QRCodeRemovedEventArgs args) {
debugScreen.text="Removed";
}
private void QR_Enum(object sender, object e) {
debugScreen.text="Enum";
}
}
}
(While the script is running the HoloLense is able to read the content of a QRCode. The debugScreen is a TextMesh so that I can see the text while wearing the HoloLense.)
Workaround to get only the recently seen QR codes to mimic the update event:
private IReadOnlyList<QRCode> detectedQR;
private DateTimeOffset timestamp;
private int timetolerance = 1; // seconds
detectedQR = qrTracker.GetList();
timestamp = DateTimeOffset.Now;
foreach (var QR in detectedQR)
{if ((timestamp - QR.LastDetectedTime ).Duration() < TimeSpan.FromSeconds(timetolerance))
{
//Do stuff with QR Codes seen in the last second
}
}
However, with too many QR codes, performance could suffer.
Hi I’m Wayne Wang from the Microsoft for Founders Hub team!
We do have an example from my colleague on your current context.
Seems the implementation you may need is here:
https://github.com/chgatla-microsoft/QRTracking/blob/master/SampleQRCodes/Assets/Scripts/QRCodesManager.cs
it was little bit of old but I believe the Interfaces and pipelines still the same

Xamarin Audio players not working in Galaxy S8

I am trying to get a shoutcast URL (.stream) to stream audio in a cross-platform application. I've started with the Android app first and I cannot get the audio playing on the test device Samsung Galaxy S8.
However, the audio players work fine within the Emulator. If it weren't for the test device I would've assumed everything was working.
I've tried using "the local MediaPlayer" and "Plugin.MediaManager": Both work in the Emulator but none on the device. I have enabled the permissions required in the manifest: ACCESS_NETWORK_STATE, INTERNET, MEDIA_CONTENT_CONTROLS, RECORD_AUDIO, WAKE_LOCK, READ_EXTERNAL_STORAGE
(using MediaManager plugin)
in MainActivy:
protected override void OnCreate(Bundle savedInstanceState)
{
.....
CrossMediaManager.Current.Init(this);
.....
}
public class StreamingService: IStreaming.IStreaming
{
bool IsPrepared = false;
public async void Play()
{
await CrossMediaManager.Current.Play("http://someUrl/stream");
}
public void Pause()
{
CrossMediaManager.Current.Pause();
}
public void Stop()
{
CrossMediaManager.Current.Stop();
IsPrepared = false;
}
public int getResponse()
{
if (CrossMediaManager.Current.IsPlaying())
return 1;
else
return 0;
}
}
If I look at the data usage for the app on the device it is set to 0kb after a few tries it goes up by the kb currently at 3.24kb data usage. It doesnt appear that the media player is trying to access the stream, or can even access the stream.
I found a nuget package: LibVLCSharp.Forms
in the Main application created a class:
using LibVLCSharp.Shared;
public class RadioStream
{
readonly LibVLC _libVLC;
readonly MediaPlayer _mp;
public RadioStream()
{
if (DesignMode.IsDesignModeEnabled) return;
Core.Initialize();
_libVLC = new LibVLC();
_mp = new MediaPlayer(_libVLC);
}
public void Init()
{
_mp.Media = new Media(_libVLC, "http://url/stream", FromType.FromLocation);
_mp.Media.AddOption(":no-video");
}
public void Play(bool play)
{
if (play)
_mp.Play();
else _mp.Pause();
}
public bool isPlaying()
{
if (_mp.IsPlaying == false)
return false;
else
return true;
}
}
And its working!
In a while loop I check the isPlaying() that allows me to set the status of the stream and display accordingly.
Its simple at the moment, and stops playing when the internet state changes. But the above is working for simple playback.

C# CSCore no sound from mp3 file

Using the CSCore library, I wrote the code for playing an mp3 file in the class BGM in a seperate file called BGM.cs and the method for playback is BGM.Play("file directory");, which is called in the Form. But somehow I can't manage to get any sound out of it. I've already checked volume, codec and output, and I can't think of anything else that might cause this problem.
This is the code of the class file:
public class BGM
{
public static void Play(string file)
{
using (IWaveSource soundSource = GetSoundSource(file))
{
using (ISoundOut soundOut = GetSoundOut())
{
soundOut.Initialize(soundSource);
soundOut.Volume = 0.8f;
soundOut.Play();
}
}
}
private static ISoundOut GetSoundOut()
{
if (WasapiOut.IsSupportedOnCurrentPlatform)
return new WasapiOut();
else
return new DirectSoundOut();
}
private static IWaveSource GetSoundSource(string file)
{
return CodecFactory.Instance.GetCodec(file);
}
There are actually a couple reasons why your mp3 isn't playing.
The first reason is you haven't specified a device for the sound to play on. The code below gets the first device that can render sound, but that won't always be correct if the user has multiple devices attached to their computer. You'll have to handle that appropriately. The device has to be set on the WasapiOut object.
The second reason is your use of using statements in your Play method. While it's always a good idea to clean up objects that implement IDisposable, you can't always do so immediately. In this case, soundOut.Play() is not a blocking method, which meant that control was exiting the method immediately, causing Dispose() to be called on soundOut and soundSource. This meant that the sound would effectively never be played (maybe it would start for a short moment, but not enough to really hear it). Essentially, you need to hold onto the references and only dispose of them once playback is complete.
Have a look at the AudioPlayerSample for an idea on how to implement a complete solution. My code should get you started.
void Main()
{
using(var player = new BGM(#"D:\Test.mp3"))
{
player.Play();
// TODO: Need to wait here in order for playback to complete
// Otherwise, you need to hold onto the player reference and dispose of it later
Console.ReadLine();
}
}
public class BGM : IDisposable
{
private bool _isDisposed = false;
private ISoundOut _soundOut;
private IWaveSource _soundSource;
public BGM(string file)
{
_soundSource = CodecFactory.Instance.GetCodec(file);
_soundOut = GetSoundOut();
_soundOut.Initialize(_soundSource);
}
public void Play()
{
if(_soundOut != null)
{
_soundOut.Volume = 0.8f;
_soundOut.Play();
}
}
public void Stop()
{
if(_soundOut != null)
{
_soundOut.Stop();
}
}
private static ISoundOut GetSoundOut()
{
if (WasapiOut.IsSupportedOnCurrentPlatform)
{
return new WasapiOut
{
Device = GetDevice()
};
}
return new DirectSoundOut();
}
private static IWaveSource GetSoundSource(string file)
{
return CodecFactory.Instance.GetCodec(file);
}
public static MMDevice GetDevice()
{
using(var mmdeviceEnumerator = new MMDeviceEnumerator())
{
using(var mmdeviceCollection = mmdeviceEnumerator.EnumAudioEndpoints(DataFlow.Render, DeviceState.Active))
{
// This uses the first device, but that isn't what you necessarily want
return mmdeviceCollection.First();
}
}
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
if(_soundOut != null)
{
_soundOut.Dispose();
}
if(_soundSource != null)
{
_soundSource.Dispose();
}
}
_isDisposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}

Keep MiDi output playing when UWP goes into background

I'm trying to build a metronome application that has the capability to run in the background. As a starting point I decided to create something simple, a class that has a timer (the metronome itself), a class responsible for obtaining the MIDI output device and a class to play the sound. I'm having difficulty with how to make this run in the background. Additionally, another problem is the fact that the metronome needs to be executed when clicking an application button (in the main process).
Metronome Class:
public class Metronome
{
private DispatcherTimer timer = new DispatcherTimer();
private MidiDeviceSelector deviceSelector = new MidiDeviceSelector();
private void TimerStart()
{
timer.Start();
timer.Tick += timer_Tick;
}
private void timer_Tick(object sender, object e)
{
AudioPlayback.Beep1();
}
public void Start(int bpm)
{
double interval = (double)60.000f / (bpm);
timer.Interval = TimeSpan.FromSeconds(interval);
TimerStart();
}
public void Stop()
{
timer.Stop();
}
}
MidiDeviceSelector:
class MidiDeviceSelector
{
public MidiDeviceSelector()
{
GetOutputMidiDevice();
}
public async void GetOutputMidiDevice()
{
IMidiOutPort currentMidiOutputDevice;
DeviceInformation devInfo;
DeviceInformationCollection devInfoCollection;
string devInfoId;
devInfoCollection = await DeviceInformation.FindAllAsync(MidiOutPort.GetDeviceSelector());
if (devInfoCollection == null)
{
//notify the user that any device was found.
System.Diagnostics.Debug.WriteLine("Any device was found.");
}
devInfo = devInfoCollection[0];
if (devInfo == null)
{
//Notify the User that the device not found
System.Diagnostics.Debug.WriteLine("Device not found.");
}
devInfoId = devInfo.Id.ToString();
currentMidiOutputDevice = await MidiOutPort.FromIdAsync(devInfoId);
if (currentMidiOutputDevice == null)
{
//Notify the User that wasn't possible to create MidiOutputPort for the device.
System.Diagnostics.Debug.WriteLine("It was not possible to create the OutPort for the device.");
}
MidiDevice.midiDevice = currentMidiOutputDevice;
}
Class to Holds the MidiDevice:
class MidiDevice
{
public static IMidiOutPort midiDevice; //Bad practice i know.
}
Class to play the "toc" sound:
class AudioPlayback
{
static IMidiMessage beep1 = new MidiNoteOnMessage(9, 76, 90);
//static IMidiOutPort midiOutputDevice = (IMidiOutPort)MidiDeviceSelector.GetOutputMidiDevice();
public static void Beep1()
{
try
{
MidiDevice.midiDevice.SendMessage(beep1);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
}
}
Each class is contained in a different file. As you can see, it is a very simple code, if you see any bad programming practice, I apologise, I do not have much experience.
I was looking at the documentation, however, I did not succeed. How do I register an activity in the background and that there is interaction with the application's user interface (a button to stop and start the metronome).
My apologies for bad English, not my native language.
Thank you.
Two things you need to add to make this scenario work:
add the "backgroundMediaPlayback" capability as documented here: https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/background-audio
since you are using the MiDI APIs, you need to explicitly integrate with the SystemMediaTransportControls to prevent getting muted on minimize
I have update your repro sample and verified that it works correctly after adding those two things.
Sharing it here for your reference: https://1drv.ms/u/s!AovTwKUMywTNl9QJTeecnDzCf0WWyQ

Call Java function from Unity3D

I have an android application developed by Unity3D written by C# and I wan to hide the bottom bar when running my app. So I searched around and found that I need to use setSystemUiVisibility function from Java. Here is the code I found:
using UnityEngine;
public class DisableSystemUI
{
static AndroidJavaObject activityInstance;
static AndroidJavaObject windowInstance;
static AndroidJavaObject viewInstance;
public delegate void RunPtr();
public static void Run()
{
if (viewInstance != null) {
viewInstance.Call("setSystemUiVisibility", 2);
}
}
static DisableSystemUI()
{
if (Application.platform != RuntimePlatform.Android)
return;
DisableNavUI();
}
static void DisableNavUI()
{
if (Application.platform != RuntimePlatform.Android)
return;
using (AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
activityInstance = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
windowInstance = activityInstance.Call<AndroidJavaObject>("getWindow");
viewInstance = windowInstance.Call<AndroidJavaObject>("getDecorView");
AndroidJavaRunnable RunThis;
RunThis = new AndroidJavaRunnable(new RunPtr(Run));
activityInstance.Call("runOnUiThread", RunThis);
}
}
}
I tried to call DisableSystemUI.Run(); in my main scene. I rooted my device but the app quits after I run it. Not sure what's wrong with it? Thanks for help.
it would be better to understand if you post the java code
i too had a same problem
try this
viewInstance.Call("setSystemUiVisibility", "SYSTEM_UI_FLAG_FULLSCREEN");
or this
viewInstance.Call("setSystemUiVisibility", "SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN");
should work....

Categories