Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.05.2012, 21:10   #1
SUDALV
Пользователь
 
Регистрация: 14.06.2010
Сообщений: 36
По умолчанию Повторитель звука

Необходимо написать программу, которая будет слушать линейный вход аудиокарты, и при появлении на нём звука, писать этот звук в буфер/файл, и после исчезновения звука (не более 10 минут) , через 2 сек тишины воспроизводить.
Сначала думал что обойдусь NAudio, но все примеры в инете указывают устройство по умолчанию (0), что не удобно.
скачал CoreAudioApi, с помощью него решилась проблема выбора устройства и определения есть ли звук.
но там нету никакой возможности записи самого звука.
соответственно подключил NAudio, но как связать их незнаю. походу никак.
кстати обнаружил NAudio.CoreAudioApi, но они не идентичны.
в NAudio.CoreAudioApi метод MMDeviceEnumerator.EnumerateAudioEn dPoints принимает совершенно другие аргументы, и не понятно что ему передать.
зато в NAudio.CoreAudioApi есть класс AudioCaptureClient , у которого есть метод GetBuffer(out int numFramesToRead, out AudioClientBufferFlags bufferFlags) - одна из 2 перегрузок.

подскажите что делать?
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using NAudio;
using NAudio.Wave;
using CoreAudioApi;

namespace Repeater
{
    public partial class MainWindow : Window
    {
        private MMDevice device;
        private MMDeviceCollection deviceCollection;
        public MainWindow()
        {
            InitializeComponent();
            MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
            deviceCollection = DevEnum.EnumerateAudioEndPoints(EDataFlow.eAll, EDeviceState.DEVICE_STATE_ACTIVE);
            for (int i = 0; i < deviceCollection.Count; i++)
            {
                deviceList.Items.Add(deviceCollection[i].FriendlyName);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            NAudio.CoreAudioApi.AudioCaptureClient captureClient = new NAudio.CoreAudioApi.AudioCaptureClient();
            captureClient.GetBuffer(4096, NAudio.CoreAudioApi.AudioClientBufferFlags.Silent,0,0);
        }

        private void deviceList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            device = deviceCollection[deviceList.SelectedIndex];
            volume.Value = device.AudioEndpointVolume.MasterVolumeLevelScalar * 100;
            device.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
            var timer = new System.Timers.Timer(1);
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Dispatcher.BeginInvoke(new Action(delegate { volumeMeter.Value = device.AudioMeterInformation.MasterPeakValue * 100; }));
        }

        void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
        {
            Dispatcher.BeginInvoke(new Action(delegate { volume.Value = (int)(data.MasterVolume * 100); }));
        }

        private void volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)volume.Value / 100.0f;
        }

    }
}
SUDALV вне форума Ответить с цитированием
Старый 01.05.2012, 21:41   #2
SUDALV
Пользователь
 
Регистрация: 14.06.2010
Сообщений: 36
По умолчанию

ок, список устройств достал, копаю дальше

Код:
for (int i = 0; i < NAudio.Mixer.Mixer.NumberOfDevices; i++)
            {                
                deviceList.Items.Add(new NAudio.Mixer.Mixer(i).Name);
            }
SUDALV вне форума Ответить с цитированием
Старый 02.05.2012, 01:33   #3
SUDALV
Пользователь
 
Регистрация: 14.06.2010
Сообщений: 36
По умолчанию

вот что в итоге получилось:
Код:
using System;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using NAudio.Wave;
using CoreAudioApi;
using System.Windows.Media;

namespace Repeater
{
    public partial class MainWindow : Window
    {
        private MMDevice device;
        private MMDeviceCollection deviceCollection;
        private WaveIn waveIn;
        private WaveFileWriter waveFile;
        private bool isRecording = false;
        public MainWindow()
        {
            InitializeComponent();
            MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
            deviceCollection = DevEnum.EnumerateAudioEndPoints(EDataFlow.eAll, EDeviceState.DEVICE_STATE_ACTIVE);
            for (int i = 0; i < NAudio.Mixer.Mixer.NumberOfDevices; i++)
            {
                deviceList.Items.Add(new NAudio.Mixer.Mixer(i).Name);
            }
        }

        private void Record()
        {
            if (!isRecording)
            {
                waveIn = new WaveIn();
                waveIn.DeviceNumber = deviceList.SelectedIndex + 1;
                waveIn.DataAvailable += waveIn_DataAvailable;
                waveIn.RecordingStopped += waveIn_RecordingStopped;
                waveIn.WaveFormat = new WaveFormat(44100, 1);
                waveFile = new WaveFileWriter("signal.wav", waveIn.WaveFormat);
                waveIn.StartRecording();
                isRecording = true;
            }
        }

        void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            waveFile.WriteAsync(e.Buffer, 0, e.BytesRecorded);
        }

        void waveIn_RecordingStopped(object sender, EventArgs e)
        {
            waveIn.Dispose();
            waveIn = null;
            waveFile.Close();
            waveFile = null;
        }

        private void deviceList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            device = deviceCollection[deviceList.SelectedIndex];
            volume.Value = device.AudioEndpointVolume.MasterVolumeLevelScalar * 100;
            device.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
            var timer = new System.Timers.Timer(1);
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {

            Dispatcher.BeginInvoke(new Action(delegate
            {
                volumeMeter.Value = device.AudioMeterInformation.MasterPeakValue * 100;
                if (device.AudioMeterInformation.MasterPeakValue*100 > 1)
                    Record();
                else Stop();
                if (volumeMeter.Value < 10)
                    volumeMeter.Foreground = Brushes.Blue;
                else if (volumeMeter.Value < 95)
                    volumeMeter.Foreground = Brushes.Green;
                else if (volumeMeter.Value > 95)
                    volumeMeter.Foreground = Brushes.Red;
            }));
        }

        private void Stop()
        {
            if (isRecording)
            {
                waveIn.StopRecording();
                isRecording = false;
            }
        }

        void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
        {
            Dispatcher.BeginInvoke(new Action(delegate { volume.Value = (int)(data.MasterVolume * 100); }));
        }

        private void volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)volume.Value / 100.0f;
        }

    }
}
начинает записывать когда идёт звук, когда звука нет, останавливает, но записывает только с устройства Speakers! Почему, понять не могу. на других тишина, а если вызвать меню "записывающие устройства" в винде, то происходит исключение.
предполагаю, что надо полностью код перенести на NAudio, но как?
SUDALV вне форума Ответить с цитированием
Старый 02.05.2012, 12:39   #4
SUDALV
Пользователь
 
Регистрация: 14.06.2010
Сообщений: 36
По умолчанию

всё, надо было проспаться просто..
от CoreAudioApi.dll избавился, теперь всё на NAudio
SUDALV вне форума Ответить с цитированием
Старый 23.05.2016, 16:40   #5
Alex Alexeenko
Новичок
Джуниор
 
Регистрация: 18.09.2012
Сообщений: 1
По умолчанию

Можете ли показать, как у вас вышло избавиться от CoreAudioApi.dll чтобы всё было на NAudio?
Alex Alexeenko вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Регулировка звука? cargo29 Мультимедиа в Delphi 5 12.01.2011 19:33
Запись звука на С++ MBelka Помощь студентам 2 06.01.2011 19:38
Пропадание звука Syltan Операционные системы общие вопросы 1 24.02.2010 07:22
Запись звука апельсинка Помощь студентам 0 03.06.2009 13:57
Проигрывание звука EdNovice Общие вопросы .NET 4 22.03.2009 20:30