コード例 #1
0
        internal void PlatformStart()
        {
            if (_state == MicrophoneState.Started)
            {
                return;
            }

            _captureDevice = Alc.CaptureOpenDevice(
                Name,
                (uint)_sampleRate,
                ALFormat.Mono16,
                GetSampleSizeInBytes(_bufferDuration));

            CheckALCError("Failed to open capture device.");

            if (_captureDevice != IntPtr.Zero)
            {
                Alc.CaptureStart(_captureDevice);
                CheckALCError("Failed to start capture.");

                _state = MicrophoneState.Started;
            }
            else
            {
                throw new NoMicrophoneConnectedException("Failed to open capture device.");
            }
        }
コード例 #2
0
ファイル: AudioDevice.cs プロジェクト: layshua/Alexandria
        public AudioCapture Capture(AudioFormat format, Frequency frequency, int bufferSampleSize = 1024 * 1024)
        {
            IntPtr result = Alc.CaptureOpenDevice(deviceName, (int)Math.Round(frequency.InHertz), (ALFormat)format, bufferSampleSize);

            if (result == IntPtr.Zero)
            {
                throw new InvalidOperationException("Cannot open the capture device.");
            }
            return(new AudioCapture(this, result, format));
        }
コード例 #3
0
        private VoipCapture(string deviceName) : base(GameMain.Client?.ID ?? 0, true, false)
        {
            VoipConfig.SetupEncoding();

            //set up capture device
            captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 5);

            if (captureDevice == IntPtr.Zero)
            {
                if (!GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "capturedevicenotfound"))
                {
                    GUI.SettingsMenuOpen = false;
                    new GUIMessageBox(TextManager.Get("Error"),
                                      TextManager.Get("VoipCaptureDeviceNotFound", returnNull: true) ?? "Could not start voice capture, suitable capture device not found.")
                    {
                        UserData = "capturedevicenotfound"
                    };
                }
                GameMain.Config.VoiceSetting = GameSettings.VoiceMode.Disabled;
                Instance?.Dispose();
                Instance = null;
                return;
            }

            int alError  = Al.GetError();
            int alcError = Alc.GetError(captureDevice);

            if (alcError != Alc.NoError)
            {
                throw new Exception("Failed to open capture device: " + alcError.ToString() + " (ALC)");
            }
            if (alError != Al.NoError)
            {
                throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
            }

            Alc.CaptureStart(captureDevice);
            alcError = Alc.GetError(captureDevice);
            if (alcError != Alc.NoError)
            {
                throw new Exception("Failed to start capturing: " + alcError.ToString());
            }

            capturing     = true;
            captureThread = new Thread(UpdateCapture)
            {
                IsBackground = true,
                Name         = "VoipCapture"
            };
            captureThread.Start();
        }
コード例 #4
0
        unsafe public AudioCapture(string device, int frequency, int channels, float duration)
        {
            this.frequency = frequency;
            this.channels  = channels;
            int bufferSize = (int)(duration * frequency * channels);

            deviceId = Alc.CaptureOpenDevice(device, frequency, channels > 1 ? ALFormat.Stereo16 : ALFormat.Mono16, bufferSize);
            buffer   = new short[bufferSize];

            fixed(short *ptr = buffer)
            {
                bufferPtr = (IntPtr)ptr;
            }
        }
コード例 #5
0
        /// <summary>Opens a device for audio recording.</summary>
        /// <param name="deviceName">The device name.</param>
        /// <param name="frequency">The frequency that the data should be captured at.</param>
        /// <param name="sampleFormat">The requested capture buffer format.</param>
        /// <param name="bufferSize">The size of OpenAL's capture internal ring-buffer. This value expects number of samples, not bytes.</param>
        public AudioCapture(string deviceName, int frequency, ALFormat sampleFormat, int bufferSize)
        {
            if (!AudioDeviceEnumerator.IsOpenALSupported)
            {
                throw new DllNotFoundException("openal32.dll");
            }
            if (frequency <= 0)
            {
                throw new ArgumentOutOfRangeException("frequency");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }

            // Try to open specified device. If it fails, try to open default device.
            device_name = deviceName;
            Handle      = Alc.CaptureOpenDevice(deviceName, frequency, sampleFormat, bufferSize);

            if (Handle == IntPtr.Zero)
            {
                Debug.WriteLine(ErrorMessage(deviceName, frequency, sampleFormat, bufferSize));
                device_name = "IntPtr.Zero";
                Handle      = Alc.CaptureOpenDevice(null, frequency, sampleFormat, bufferSize);
            }

            if (Handle == IntPtr.Zero)
            {
                Debug.WriteLine(ErrorMessage("IntPtr.Zero", frequency, sampleFormat, bufferSize));
                device_name = AudioDeviceEnumerator.DefaultRecordingDevice;
                Handle      = Alc.CaptureOpenDevice(AudioDeviceEnumerator.DefaultRecordingDevice, frequency, sampleFormat, bufferSize);
            }

            if (Handle == IntPtr.Zero)
            {
                // Everything we tried failed. Capture may not be supported, bail out.
                Debug.WriteLine(ErrorMessage(AudioDeviceEnumerator.DefaultRecordingDevice, frequency, sampleFormat, bufferSize));
                device_name = "None";

                throw new AudioDeviceException("All attempts to open capture devices returned IntPtr.Zero. See debug log for verbose list.");
            }

            // handle is not null, check for some Alc Error
            CheckErrors();

            SampleFormat    = sampleFormat;
            SampleFrequency = frequency;
        }
コード例 #6
0
        private VoipCapture(string deviceName) : base(GameMain.Client?.ID ?? 0, true, false)
        {
            Disconnected = false;

            VoipConfig.SetupEncoding();

            //set up capture device
            captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 5);

            if (captureDevice == IntPtr.Zero)
            {
                DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 1 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(), Color.Orange);
                //attempt using a smaller buffer size
                captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 2);
            }

            if (captureDevice == IntPtr.Zero)
            {
                DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 2 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(), Color.Orange);
                //attempt using the default device
                captureDevice = Alc.CaptureOpenDevice("", VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 2);
            }

            if (captureDevice == IntPtr.Zero)
            {
                string errorCode = Alc.GetError(IntPtr.Zero).ToString();
                if (!GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "capturedevicenotfound"))
                {
                    GUI.SettingsMenuOpen = false;
                    new GUIMessageBox(TextManager.Get("Error"),
                                      (TextManager.Get("VoipCaptureDeviceNotFound", returnNull: true) ?? "Could not start voice capture, suitable capture device not found.") + " (" + errorCode + ")")
                    {
                        UserData = "capturedevicenotfound"
                    };
                }
                GameAnalyticsManager.AddErrorEventOnce("Alc.CaptureDeviceOpenFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                                                       "Alc.CaptureDeviceOpen(" + deviceName + ") failed. Error code: " + errorCode);
                GameMain.Config.VoiceSetting = GameSettings.VoiceMode.Disabled;
                Instance?.Dispose();
                Instance = null;
                return;
            }

            int alError  = Al.GetError();
            int alcError = Alc.GetError(captureDevice);

            if (alcError != Alc.NoError)
            {
                throw new Exception("Failed to open capture device: " + alcError.ToString() + " (ALC)");
            }
            if (alError != Al.NoError)
            {
                throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
            }

            CanDetectDisconnect = Alc.IsExtensionPresent(captureDevice, "ALC_EXT_disconnect");
            alcError            = Alc.GetError(captureDevice);
            if (alcError != Alc.NoError)
            {
                throw new Exception("Error determining if disconnect can be detected: " + alcError.ToString());
            }

            Alc.CaptureStart(captureDevice);
            alcError = Alc.GetError(captureDevice);
            if (alcError != Alc.NoError)
            {
                throw new Exception("Failed to start capturing: " + alcError.ToString());
            }

            capturing     = true;
            captureThread = new Thread(UpdateCapture)
            {
                IsBackground = true,
                Name         = "VoipCapture"
            };
            captureThread.Start();
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: stepanbenes/ClapDetector
        static async Task Main(string[] args)
        {
            // =============================================================================================================
            // inspired by: https://stackoverflow.com/questions/4087727/openal-how-to-create-simple-microphone-echo-programm

            string captureDeviceSpecifier = Alc.GetString(IntPtr.Zero, Alc.CaptureDeviceSpecifier);

            Console.WriteLine("Capture device name: " + captureDeviceSpecifier);

            //var audioDevice = Alc.OpenDevice(null);

            ////var errorCode = Alc.GetError(audioDevice); // TODO: check this after each Alc call
            ////var errorCode = Al.GetError(); // TODO: check this after each Al call

            //var context = Alc.CreateContext(audioDevice, null);
            //Alc.MakeContextCurrent(context);

            const int frequency     = 44100;
            const int keywordLength = (int)(frequency);

            var captureDevice = Alc.CaptureOpenDevice(captureDeviceSpecifier, frequency, format: Al.FormatMono16, buffersize: frequency);

            string deviceName = Alc.GetString(captureDevice, Alc.DeviceSpecifier);

            Console.WriteLine($"{deviceName} is open for capture.");

            if (args.Length > 0 && args[0] == "record")
            {
                while (true)
                {
                    Console.Write("Enter keyword name: ");
                    string keywordName = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(keywordName))                     // exit if nothing entered
                    {
                        break;
                    }

                    Alc.CaptureStart(captureDevice);
                    Console.WriteLine("recording keyword...");                     // need new line for intensity visualization

                    short[] samples = captureSamples(captureDevice, frequency, keywordLength);

                    Alc.CaptureStop(captureDevice);

                    int fileIndex = 0;
                    while (File.Exists($"{keywordName}.{fileIndex}.wav"))
                    {
                        fileIndex += 1;
                    }

                    // write sound file
                    {
                        string filename = $"{keywordName}.{fileIndex}.wav";
                        Debug.Assert(samples.Length >= keywordLength);
                        var wavFile = new WavFile(filename)
                        {
                            SamplesPerSecond = frequency, SamplesTotalCount = keywordLength                                                           /* trim samples */
                        };
                        wavFile.WriteMono16bit(samples);
                        Console.WriteLine($"wav file was saved.");
                    }

                    // create spectrogram and save as image
                    {
                        int width = (int)Math.Sqrt(samples.Length * 2);                         // TODO: make better formula for square images
                        var bins  = samples.Partition(size: width);

                        var spectrogram = new List <double[]>();

                        foreach (var bin in bins)
                        {
                            double[] histogram = calculateFFT(bin.ToArray());
                            spectrogram.Add(histogram);
                        }

                        using (Bitmap bitmap = new Bitmap(spectrogram.Count, spectrogram[0].Length))
                        {
                            for (int i = 0; i < spectrogram.Count; i++)
                            {
                                for (int j = 0; j < spectrogram[i].Length; j++)
                                {
                                    double value      = spectrogram[i][j];
                                    double pixelValue = Math.Max(0, Math.Min(255, value * 10));                                     // TODO: do not trim values, make better multiplying factor
                                    byte   color      = (byte)(pixelValue);
                                    bitmap.SetPixel(i, j, Color.FromArgb(color, color, color));
                                }
                            }
                            string filename = $"{keywordName}.{fileIndex}.png";
                            bitmap.Save(filename, ImageFormat.Png);
                            Console.WriteLine($"png file was saved.");
                        }
                    }
                }
            }
            else
            {
                Alc.CaptureStart(captureDevice);
                Console.WriteLine("listening for keyword...");                 // need new line for intensity visualization
                var reporter = new ClapDetector.Client.Reporter();
                while (true)
                {
                    short[] samples = captureSamples(captureDevice, frequency, keywordLength);
                    // TODO: generate spectrogram image and compare to existing models
                    Console.WriteLine("samples taken");

                    string replyMessage = await reporter.ReportClapAsync();

                    System.Console.WriteLine($"[{DateTime.UtcNow:HH:mm:ss.fff}]: {replyMessage}");
                }
                Alc.CaptureStop(captureDevice);
            }

            // clean up
            Alc.CaptureCloseDevice(captureDevice);
            Alc.MakeContextCurrent(IntPtr.Zero);
            //Alc.DestroyContext(context);
            //Alc.CloseDevice(audioDevice);
        }