첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.01MB

▶ ControlExtension.cs

using System;
using System.Windows.Controls;
using System.Windows.Threading;

namespace TestProject
{
    /// <summary>
    /// 컨트롤 확장
    /// </summary>
    public static class ControlExtension
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 필요시 UI 스레드에서 호출하기 - InvokeOnUIThreadIfRequired(control, action)

        /// <summary>
        /// 필요시 UI 스레드에서 호출하기
        /// </summary>
        /// <param name="control">컨트롤</param>
        /// <param name="action">액션</param>
        public static void InvokeOnUIThreadIfRequired(this Control control, Action action)
        {
            if(!control.Dispatcher.CheckAccess())
            {
                control.Dispatcher.BeginInvoke
                (
                    DispatcherPriority.Normal,
                    new Action(delegate () { action(); })
                );
            }
            else
            {
                action.Invoke();
            }
        }

        #endregion
    }
}

 

728x90

 

▶ AudioControl.xaml

<UserControl x:Class="TestProject.AudioControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <UserControl.Resources>
        <Style x:Key="SliderRepeatButtonStyleKey" TargetType="{x:Type RepeatButton}">
            <Setter Property="OverridesDefaultStyle" Value="true"  />
            <Setter Property="Focusable"             Value="false" />
            <Setter Property="IsTabStop"             Value="false" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RepeatButton}">
                        <Rectangle Fill="Transparent" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="HorizontalSliderThumbStyleKey" TargetType="{x:Type Thumb}">
            <Setter Property="Width"                 Value="16"    />
            <Setter Property="Height"                Value="16"    />
            <Setter Property="OverridesDefaultStyle" Value="true"  />
            <Setter Property="Focusable"             Value="false" />
            <Setter Property="Foreground"            Value="Gray"  />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Thumb}">
                        <Ellipse
                            StrokeThickness="0.8"
                            Stroke="#ff5e5d5d"
                            Fill="#ffaed1ed" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="{x:Type Slider}">
            <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"       />
            <Setter Property="Background"                   Value="Transparent" />
            <Setter Property="Foreground"                   Value="#ffc4c4c4"   />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Slider}">
                        <Border
                            BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}"
                            SnapsToDevicePixels="true">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition MinHeight="{TemplateBinding MinHeight}" Height="Auto" />
                                    <RowDefinition                                         Height="Auto" />
                                </Grid.RowDefinitions>
                                <Border Grid.Row="1"
                                    VerticalAlignment="Center"
                                    Margin="5 0"
                                    Height="10"
                                    CornerRadius="1">
                                    <Grid>
                                        <Border
                                            CornerRadius="0.5"
                                            Background="#fff7f4f4"
                                            Opacity="0.215" />
                                        <Border
                                            Margin="0 0 0.3 0.3"
                                            CornerRadius="0.5"
                                            Background="#ff132e50"
                                            Opacity="0.715" />
                                    </Grid>
                                </Border>
                                <Track Name="PART_Track" Grid.Row="1">
                                    <Track.DecreaseRepeatButton>
                                        <RepeatButton
                                            Style="{StaticResource SliderRepeatButtonStyleKey}"
                                            Command="{x:Static Slider.DecreaseLarge}" />
                                    </Track.DecreaseRepeatButton>
                                    <Track.IncreaseRepeatButton>
                                        <RepeatButton
                                            Style="{StaticResource SliderRepeatButtonStyleKey}"
                                            Command="{x:Static Slider.IncreaseLarge}" />
                                    </Track.IncreaseRepeatButton>
                                    <Track.Thumb>
                                        <Thumb Style="{StaticResource HorizontalSliderThumbStyleKey}" />
                                    </Track.Thumb>
                                </Track>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="0.5" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="CustomProgressBarBackgroundSolidColorBrushKey"
            Color="#55ffffff" />
        <Style x:Key="ProgressBarStyleKey" TargetType="{x:Type ProgressBar}">
            <Setter Property="Height"          Value="5"   />
            <Setter Property="BorderThickness" Value="0"   />
            <Setter Property="Background"      Value="{StaticResource CustomProgressBarBackgroundSolidColorBrushKey}" />
            <Setter Property="Minimum"         Value="0"   />
            <Setter Property="Maximum"         Value="100" />
        </Style>
    </UserControl.Resources>
    <Border
        BorderThickness="1"
        BorderBrush="Black"
        Padding="1">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <ComboBox Name="microphoneComboBox" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
                Width="250"
                Height="25" />
            <Button Name="openSoundControlButton" Grid.Row="0" Grid.RowSpan="2" Grid.Column="3"
                Margin="5 0 0 0"
                Width="70"
                Content="제어판" />
            <Button Name="muteMicrophoneButton" Grid.Row="1" Grid.Column="0"
                Margin="0 5 0 5"
                Width="20"
                Height="20"
                Content=""
                Background="#ff4fed82" />
            <Slider Name="volumeSlider" Grid.Row="1" Grid.Column="1"
                VerticalAlignment="Center"
                Width="90"
                Maximum="100"
                TickFrequency="10"
                SmallChange="1"
                Value="-1" />
            <ProgressBar Name="volumeProgressBar" Grid.Row="1" Grid.Column="2"
                Style="{DynamicResource ProgressBarStyleKey}"
                VerticalAlignment="Center"
                Width="80"
                Height="20"
                Background="#55050000"
                IsIndeterminate="False"
                Value="50" />
        </Grid>
    </Border>
</UserControl>

 

반응형

 

▶ AudioControl.xaml.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

using AudioSwitcher.AudioApi;
using AudioSwitcher.AudioApi.CoreAudio;
using AudioSwitcher.AudioApi.Observables;

using NAudio.CoreAudioApi;
using NAudio.Wave;

namespace TestProject
{
    /// <summary>
    /// 오디오 컨트롤
    /// </summary>
    public partial class AudioControl : UserControl
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 코어 오디오 장치 리스트
        /// </summary>
        private List<CoreAudioDevice> coreAudioDeviceList = null;

        /// <summary>
        /// 디폴트 코어 오디오 장치
        /// </summary>
        private CoreAudioDevice defaultCoreAudioDevice = null;

        /// <summary>
        /// 코어 오디오 컨트롤러
        /// </summary>
        private CoreAudioController coreAudioController = null;

        /// <summary>
        /// Disposable 리스트
        /// </summary>
        private List<IDisposable> disposableList = null;

        /// <summary>
        /// 볼륨 변경 액션
        /// </summary>
        private Action<DeviceVolumeChangedArgs> changeVolumeAction = null;

        /// <summary>
        /// 음소거 변경 액션
        /// </summary>
        private Action<DeviceMuteChangedArgs> changeMuteMicrophoneAction = null;

        /// <summary>
        /// 디폴트 장치 변경 액션
        /// </summary>
        private Action<DefaultDeviceChangedArgs> changeDefaultDeviceAction = null;

        /// <summary>
        /// 장치 상태 변경 액션
        /// </summary>
        private Action<DeviceStateChangedArgs> changeDeviceStateAction = null;

        /// <summary>
        /// 멀티미디어 장치 열거자
        /// </summary>
        private MMDeviceEnumerator mmDeviceEnumerator = null;

        /// <summary>
        /// 웨이브 입력 이벤트
        /// </summary>
        private WaveInEvent waveInEvent = null;

        /// <summary>
        /// 중단 여부
        /// </summary>
        private bool stopped = false;

        /// <summary>
        /// 최대 오디오 값
        /// </summary>
        private double maximumAudioValue = 0;

        /// <summary>
        /// 마지막 오디오 값
        /// </summary>
        private double lastAudioValue = 0;

        /// <summary>
        /// 샘플 비율
        /// </summary>
        private const int SAMPLE_RATE = 44100;

        /// <summary>
        /// 버퍼 샘플 수
        /// </summary>
        private const int BUFFER_SAMPLE_COUNT = 1024;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - AudioControl()

        /// <summary>
        /// 생성자
        /// </summary>
        public AudioControl()
        {
            InitializeComponent();

            Loaded                                   += UserControl_Loaded;
            Unloaded                                 += UserControl_Unloaded;
            this.microphoneComboBox.SelectionChanged += microphoneComboBox_SelectionChanged;
            this.openSoundControlButton.Click        += openSoundControlButton_Click;
            this.muteMicrophoneButton.Click          += muteMicrophoneButton_Click;
            this.volumeSlider.ValueChanged           += volumeSlider_ValueChanged;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 사용자 컨트롤 로드시 처리하기 - UserControl_Loaded(sender, e)

        /// <summary>
        /// 사용자 컨트롤 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.microphoneComboBox.Cursor = Cursors.Hand;

            this.muteMicrophoneButton.Cursor = Cursors.Hand;

            this.volumeSlider.Cursor  = Cursors.Hand;
            this.volumeSlider.Maximum = 100;
            this.volumeSlider.Value   = 0;

            this.volumeProgressBar.Value = 0;

            this.openSoundControlButton.Cursor = Cursors.Hand;

            this.changeVolumeAction         = ChangeVolume;
            this.changeMuteMicrophoneAction = ChangeMuteMicrophone;
            this.changeDefaultDeviceAction  = ChangeDefaultDevice;
            this.changeDeviceStateAction    = ChangeDeviceState;

            this.disposableList = new List<IDisposable>();

            this.mmDeviceEnumerator = new MMDeviceEnumerator();

            this.coreAudioController = new CoreAudioController();

            SetCoreAudioDeviceList();

            SetControl();
        }

        #endregion
        #region 사용자 컨트롤 언로드시 처리하기 - UserControl_Unloaded(sender, e)

        /// <summary>
        /// 사용자 컨트롤 언로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            if(this.defaultCoreAudioDevice != null)
            {
                this.defaultCoreAudioDevice.Dispose();
            }

            if(this.coreAudioController != null)
            {
                this.coreAudioController.Dispose();
            }

            if(this.mmDeviceEnumerator != null)
            {
                this.mmDeviceEnumerator.Dispose();
            }

            if(this.waveInEvent != null)
            {
                this.waveInEvent.Dispose();
            }
        }

        #endregion
        #region 마이크로폰 콤보 박스 선택 변경시 처리하기 - microphoneComboBox_SelectionChanged(sender, e)

        /// <summary>
        /// 마이크로폰 콤보 박스 선택 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void microphoneComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(this.microphoneComboBox.SelectedIndex > -1)
            {
                if(!this.defaultCoreAudioDevice.FullName.Equals(this.microphoneComboBox.SelectedItem.ToString()))
                {
                    CoreAudioDevice coreAudioDevice = this.coreAudioDeviceList.Find(x => x.FullName.Equals(this.microphoneComboBox.SelectedItem.ToString()));

                    if(coreAudioDevice != null)
                    {
                        this.coreAudioController.SetDefaultDevice(coreAudioDevice);
                    }
                }
            }
        }

        #endregion
        #region 사운드 컨트롤 열기 버튼 클릭시 처리하기 - openSoundControlButton_Click(sender, e)

        /// <summary>
        /// 사운드 컨트롤 열기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void openSoundControlButton_Click(object sender, RoutedEventArgs e)
        {
            // 제어판/소리/녹음 탭을 연다(마지막 0은 재생 탭, 1은 녹음 탭)
            Process.Start("rundll32", "Shell32.dll,Control_RunDLL Mmsys.cpl,,1");
        }

        #endregion
        #region 마이크로폰 음소거 버튼 클릭시 처리하기 - muteMicrophoneButton_Click(sender, e)

        /// <summary>
        /// 마이크로폰 음소거 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void muteMicrophoneButton_Click(object sender, RoutedEventArgs e)
        {
            if(this.defaultCoreAudioDevice != null)
            {
                this.defaultCoreAudioDevice.Mute(!this.defaultCoreAudioDevice.IsMuted);
            }
        }

        #endregion
        #region 볼륨 슬라이더 값 변경시 처리하기 - volumeSlider_ValueChanged(sender, e)

        /// <summary>
        /// 볼륨 슬라이더 값 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void volumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if(this.defaultCoreAudioDevice != null)
            {
                this.defaultCoreAudioDevice.Volume = (int)e.NewValue;
            }
        }

        #endregion

        #region 웨이브 입력 이벤트 데이터 이용 가능시 처리하기 - waveInEvent_DataAvailable(sender, e)

        /// <summary>
        /// 웨이브 입력 이벤트 데이터 이용 가능시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void waveInEvent_DataAvailable(object sender, WaveInEventArgs e)
        {
            float maximum = 0;

            for(int i = 0; i < e.BytesRecorded; i += 2)
            {
                short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]);

                float sampleFloat = sample / 32768f;

                if(sampleFloat < 0)
                {
                    sampleFloat = -sampleFloat;
                }

                if(sampleFloat > maximum)
                {
                    maximum = sampleFloat;
                }
            }

            if(maximum > this.maximumAudioValue)
            {
                this.maximumAudioValue = (double)maximum;
            }

            this.lastAudioValue = maximum;

            double fraction = this.lastAudioValue / this.maximumAudioValue;

            this.InvokeOnUIThreadIfRequired(() => this.volumeProgressBar.Value = (int)(fraction * this.volumeProgressBar.Width));
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region Disposable 리스트 지우기 - ClearDisposableList()

        /// <summary>
        /// Disposable 리스트 지우기
        /// </summary>
        private void ClearDisposableList()
        {
            if(this.disposableList != null)
            {
                if(this.disposableList.Count > 0)
                {
                    foreach(IDisposable disposable in this.disposableList)
                    {
                        disposable.Dispose();
                    }
                }

                this.disposableList.Clear();
            }
        }

        #endregion
        #region 코어 오디어 장치 리스트 설정하기 - SetCoreAudioDeviceList()

        /// <summary>
        /// 코어 오디어 장치 리스트 설정하기
        /// </summary>
        private void SetCoreAudioDeviceList()
        {
            if(this.coreAudioDeviceList == null)
            {
                this.coreAudioDeviceList = new List<CoreAudioDevice>();
            }
            else
            {
                this.coreAudioDeviceList.Clear();
            }

            IEnumerable<CoreAudioDevice> deviceEnumerable = this.coreAudioController.GetCaptureDevices().Where
            (
                device => !device.FullName.Contains("Unknown") && device.State.Equals(AudioSwitcher.AudioApi.DeviceState.Active)
            );

            foreach(CoreAudioDevice coreAudioDevice in deviceEnumerable)
            {
                this.coreAudioDeviceList.Add(coreAudioDevice);
            }
                
            if(this.coreAudioDeviceList.Count > 0)
            {
                ClearDisposableList();

                this.defaultCoreAudioDevice = this.coreAudioController.DefaultCaptureDevice;

                for(int i = 0; i < this.coreAudioDeviceList.Count; i++)
                {
                    CoreAudioDevice device = this.coreAudioDeviceList[i];

                    this.disposableList.Add(ObservableExtensions.Subscribe(device.VolumeChanged , changeVolumeAction        ));
                    this.disposableList.Add(ObservableExtensions.Subscribe(device.MuteChanged   , changeMuteMicrophoneAction));
                    this.disposableList.Add(ObservableExtensions.Subscribe(device.DefaultChanged, changeDefaultDeviceAction ));
                    this.disposableList.Add(ObservableExtensions.Subscribe(device.StateChanged  , changeDeviceStateAction   ));
                }
            }
        }

        #endregion
        #region 장치 인덱스 구하기 - GetDeviceIndex()

        /// <summary>
        /// 장치 인덱스 구하기
        /// </summary>
        /// <returns>장치 인덱스</returns>
        private int? GetDeviceIndex()
        {
            MMDevice device = this.mmDeviceEnumerator.GetDefaultAudioEndpoint
            (
                DataFlow.Capture,
                NAudio.CoreAudioApi.Role.Multimedia
            );

            int? deviceIndex = 0;

            if(device != null)
            {
                for(int i = 0; i < WaveIn.DeviceCount; i++)
                {
                    if(device.FriendlyName.Equals(WaveIn.GetCapabilities(i).ProductName))
                    {
                        deviceIndex = i;

                        break;
                    }
                }
            }
            else
            {
                return null;
            }

            return deviceIndex;
        }

        #endregion
        #region 웨이브 입력 이벤트 설정하기 - SetWaveInEvent(waveInEvent)

        /// <summary>
        /// 웨이브 입력 이벤트 설정하기
        /// </summary>
        /// <param name="waveInEvent">웨이브 입력 이벤트</param>
        private void SetWaveInEvent(ref WaveInEvent waveInEvent)
        {
            int? deviceIndex = GetDeviceIndex();

            if(deviceIndex != null)
            {
                waveInEvent = new WaveInEvent();

                waveInEvent.DeviceNumber       = (int)deviceIndex;
                waveInEvent.WaveFormat         = new WaveFormat(44100, 16, 1);
                waveInEvent.BufferMilliseconds = (int)((double)BUFFER_SAMPLE_COUNT / (double)SAMPLE_RATE * 1000.0);

                waveInEvent.DataAvailable    += waveInEvent_DataAvailable;
                waveInEvent.RecordingStopped += (sender, e) => this.stopped = false;
                
                this.InvokeOnUIThreadIfRequired(() => this.volumeProgressBar.Value = 0);
            }
        }

        #endregion
        #region 컨트롤 설정하기 - SetControl()

        /// <summary>
        /// 컨트롤 설정하기
        /// </summary>
        private void SetControl()
        {
            try
            {
                lock(this.microphoneComboBox)
                {
                    this.InvokeOnUIThreadIfRequired(() => this.microphoneComboBox.Items.Clear());

                    if(this.coreAudioDeviceList != null && this.coreAudioDeviceList.Count > 0 && this.defaultCoreAudioDevice != null)
                    {
                        Action<int> action = (count) =>
                        {
                            for(int i = 0; i < count; i++)
                            {
                                this.microphoneComboBox.Items.Add(this.coreAudioDeviceList[i].FullName);
                            }

                            this.microphoneComboBox.SelectedIndex = this.coreAudioDeviceList.IndexOf(this.defaultCoreAudioDevice);
                        };

                        this.InvokeOnUIThreadIfRequired(() => action(this.coreAudioDeviceList.Count));

                        if(this.waveInEvent == null)
                        {
                            SetWaveInEvent(ref this.waveInEvent);
                        }

                        if((int)this.defaultCoreAudioDevice.Volume > -1)
                        {
                            this.InvokeOnUIThreadIfRequired(() => this.volumeSlider.Value = (int)this.defaultCoreAudioDevice.Volume);
                        }

                        if(this.defaultCoreAudioDevice.IsMuted)
                        {
                            this.InvokeOnUIThreadIfRequired(() => this.muteMicrophoneButton.Background = (SolidColorBrush)new BrushConverter().ConvertFromString("red"));

                            if(this.waveInEvent != null)
                            {
                                this.waveInEvent.StopRecording();

                                this.stopped = false;

                                this.InvokeOnUIThreadIfRequired(() => this.volumeProgressBar.Value = 0);
                            }
                        }
                        else
                        {
                            this.InvokeOnUIThreadIfRequired(() => this.muteMicrophoneButton.Background = (SolidColorBrush)new BrushConverter().ConvertFromString("green"));

                            if(this.waveInEvent != null && !this.stopped)
                            {
                                this.waveInEvent.StartRecording();

                                this.stopped = true;
                            }
                        }
                    }
                    else
                    {
                        this.InvokeOnUIThreadIfRequired(() => this.microphoneComboBox.SelectedIndex = -1);
                    }
                }
            }
            catch(Exception exception)
            {
                MessageBox.Show(exception.ToString());
            }
        }

        #endregion

        #region 볼륨 변경하기 - ChangeVolume(e)

        /// <summary>
        /// 볼륨 변경하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        private void ChangeVolume(DeviceVolumeChangedArgs e)
        {
            if(e.Device.FullName.Equals(this.defaultCoreAudioDevice.FullName))
            {
                this.InvokeOnUIThreadIfRequired(() => this.volumeSlider.Value = (int)e.Volume);
            }
        }

        #endregion
        #region 마이크로폼 음소거 변경하기 - ChangeMuteMicrophone(e)

        /// <summary>
        /// 마이크로폼 음소거 변경하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        private void ChangeMuteMicrophone(DeviceMuteChangedArgs e)
        {
            if(e.Device.FullName.Equals(this.defaultCoreAudioDevice.FullName))
            {
                SetCoreAudioDeviceList();

                SetControl();
            }
        }

        #endregion
        #region 디폴트 장치 변경하기 - ChangeDefaultDevice(e)

        /// <summary>
        /// 디폴트 장치 변경하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        private void ChangeDefaultDevice(DefaultDeviceChangedArgs e)
        {
            if(((CoreAudioDevice)e.Device).IsDefaultDevice)
            {
                if(this.waveInEvent != null)
                {
                    this.waveInEvent.StopRecording();

                    this.waveInEvent.DataAvailable -= waveInEvent_DataAvailable;

                    this.waveInEvent = null;
                }

                SetCoreAudioDeviceList();

                SetControl();
            }
        }

        #endregion
        #region 장치 상태 변경하기 - ChangeDeviceState(e)

        /// <summary>
        /// 장치 상태 변경하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        private void ChangeDeviceState(DeviceStateChangedArgs e)
        {
            this.InvokeOnUIThreadIfRequired(() => this.volumeProgressBar.Value = 0);

            if(((CoreAudioDevice)e.Device).IsDefaultDevice)
            {
                if(this.waveInEvent != null)
                {
                    this.waveInEvent.StopRecording();

                    this.waveInEvent.DataAvailable -= waveInEvent_DataAvailable;

                    this.waveInEvent = null;
                }
            }

            SetCoreAudioDeviceList();

            SetControl();
        }

        #endregion
    }
}

 

300x250

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject"
    Width="800"
    Height="600"
    Title="마이크로폰 볼륨 설정하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Grid>
        <local:AudioControl />
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System.Windows;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요