Click here to Skip to main content
14,039,365 members
Click here to Skip to main content

Stats

748.8K views
30.2K downloads
281 bookmarked
Posted 14 Sep 2010
Licenced CPOL

PVS.AVPlayer - MCI Audio and Video Library

, 7 Aug 2018
Windows Media Control Interface (MCI) library with many added features
PVS.AVPlayer
PVS.AVPlayer .NET 2.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 3.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 3.5
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.0
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.5
PVS.AVPlayer .NET 4.5.1
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.5.2
PVS.AVPlayer.XML
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6.1
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.6.2
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.7
PVS.AVPlayer .NET 4.7.1
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer .NET 4.7.2
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer.dll
PVS.AVPlayer.XML
PVS.AVPlayer All Source Code
AVPlayerExample
AVPlayerExample
AVPlayerExample.csproj.user
bin
Debug
PVS.AVPlayer.XML
Release
Dialogs
Display Overlays
obj
Debug
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
WingDings3a.ttf
Voice Recorder
FolderView
FolderView
bin
Debug
PVS.AVPlayer.XML
Release
FolderView.csproj.user
obj
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
PVS.AVPlayer
AVPlayerExample.csproj.user
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Custom Items
Native Methods
Bob.png
Crystal Italic1.ttf
Dial Green 2.png
Dial Green 4.png
Dial Green.png
Dial Red 2.png
Dial Red.png
media7.ico
media7a.ico
Media8.ico
Media8a.ico
VU Meter.png
WingDings3a.ttf
Sound Recorder
Various
About Dialog
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Custom Items
FolderView.csproj.user
Debug
Bob.png
Crystal Italic1.ttf
media7a.ico
media7b.ico
Media8a.ico
Media8b.ico
Subtitles Overlay
Various
How To (C#)
PVSAVPlayerHowTo
bin
Debug
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Release
obj
Debug
Release
Properties
How To (VB.NET)
PVSAVPlayerHowToVB
bin
Debug
PVS.AVPlayer.dll
PVS.AVPlayer.XML
Release
My Project
Application.myapp
obj
Debug
Release
PVSAVPlayerHowTo.vbproj.user
PVS.AVPlayer Examples
AVPlayerExample.ex_
FolderView.ex_
AVPlayerExample.exe
FolderView.exe
PVS.AVPlayer.dll
#region Usings

using System;
using System.Drawing;
using System.Windows.Forms;
using PVS.AVPlayer;

#endregion

namespace AVPlayerExample
{
    public partial class SoundRecorder : Form
    {
        /*
        
        Sound Recorder - using the PVS.AVPlayer Recorder Class to
        record sound (microphone or other input) with the MCI WaveAudio Device.
        
        */

        // ******************************** Fields

        #region Fields

        // Constants
        private const int   NO_ERROR = 0;
        private const int   WARNING_FILESIZE = 1;
        private const int   WARNING_MICROPHONE = 328;

        // Recorder
        private Recorder    _soundRecorder;

        // Various
        private MainWindow  _baseForm;
        private SoundPlayer _soundPlayer;   // to pass on filename of last recording
        private Font        _crystalFont20;

        private bool        _recFlash;      // record button flashing state
        private bool        _pauseFlash;    // pause button flashing state

        // Output level meter
        private Channels    _levelChannels;
        private Bits        _levelBits;
        private double      _levelUnits;
        private int         _leftLevel;
        private int         _rightLevel;
        private SolidBrush  _levelBrush;

        private bool        _disposed;

        #endregion

        // ******************************** Main

        #region Main

        public SoundRecorder(MainWindow baseForm, SoundPlayer soundPlayer)
        {
            InitializeComponent();

            // Create recorder with eventhandlers:
            _soundRecorder = new Recorder();
            _soundRecorder.InputDevice.Index = 0; // set system default input device (if any)

            // set peak meter
            _levelBrush = new SolidBrush(MainWindow.Prefs.RecorderLevelMeterColor);
            SetInputLevelMeter();
            leftLevelPanel.Paint += LeftLevelPanel_Paint;
            rightLevelPanel.Paint += RightLevelPanel_Paint;

            // Save recording when stopped (and length > 0):
            _soundRecorder.Events.RecorderSaveRequest += _soundRecorder_SaveRequest;
            // Update time counter display: - see SoundRecorder_VisibleChanged
            //_soundRecorder.RecorderPositionChanged += _soundRecorder_PositionChanged;
            // Flashing record button:
            _soundRecorder.Events.RecorderStarted += _soundRecorder_StartStop;
            _soundRecorder.Events.RecorderStopped += _soundRecorder_StartStop;
            // Flashing pause button:
            _soundRecorder.Events.RecorderPaused += _soundRecorder_PauseResume;
            _soundRecorder.Events.RecorderResumed += _soundRecorder_PauseResume;
            // Detect single (mono) or double (stereo) peak meter:
            _soundRecorder.Events.RecorderChannelsChanged += _soundRecorder_RecorderChannelsChanged;
            // Detect 8 or 16-bits peak meter:
            _soundRecorder.Events.RecorderBitsChanged += _soundRecorder_RecorderBitsChanged;
            // Peak level meter display: - see SoundRecorder_VisibleChanged
            //_soundRecorder.RecorderInputLevelChanged += _soundRecorder_RecorderInputLevelChanged;

            selectDeviceMenuItem.DropDown.Opening += SelectDeviceMenu_Opening;
            selectDeviceMenuItem.DropDown.ItemClicked += SelectDeviceMenuDropDown_ItemClicked;
            _soundRecorder.Events.RecorderInputDeviceChanged += _soundRecorder_RecorderInputDeviceChanged;

            // Form handling
            _baseForm = baseForm;
            Owner = _baseForm;
            _soundPlayer = soundPlayer;

            // Set font
            _crystalFont20 = new Font(_baseForm.FontCollection.Families[0], 20, FontStyle.Italic);
            recCounterLabel.Font = _crystalFont20;
            recCounterLabel.UseCompatibleTextRendering = true;
        }

        // no need to update position and peak level when hidden (stop timer in lib)
        private void SoundRecorder_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                _soundRecorder.Events.RecorderPositionChanged += _soundRecorder_PositionChanged;
                _soundRecorder.Events.RecorderInputLevelChanged += _soundRecorder_RecorderInputLevelChanged;
            }
            else
            {
                _soundRecorder.Events.RecorderPositionChanged -= _soundRecorder_PositionChanged;
                _soundRecorder.Events.RecorderInputLevelChanged -= _soundRecorder_RecorderInputLevelChanged;
            }
        }

        protected override bool ShowWithoutActivation
        {
            get { return true; }
        }

        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    if (_pauseFlash) ButtonFlash.Remove(pauseButton);
                    if (_recFlash) ButtonFlash.Remove(recordButton);

                    if (_soundRecorder != null)
                    {
                        _soundRecorder.Dispose(); _soundRecorder = null;
                        _levelBrush.Dispose(); _levelBrush = null;
                    }
                    _crystalFont20.Dispose(); _crystalFont20 = null;

                    if (components != null) components.Dispose();
                }
                _disposed = true;
            }
            base.Dispose(disposing);
        }

        #endregion

        // ******************************** Recorder Event Handling

        #region Recorder Event Handling

        // Start/Stop flashing record button
        void _soundRecorder_StartStop(object sender, EventArgs e)
        {
            if (_soundRecorder.Recording)
            {
                if (!_recFlash) // no need for this var?
                {
                    ButtonFlash.Add(recordButton, recordButton.ForeColor, Color.Black);
                    _recFlash = true;
                }
            }
            else
            {
                if (_recFlash)
                {
                    ButtonFlash.Remove(recordButton);
                    _recFlash = false;
                }
            }
        }

        // Start/Stop flashing pause button
        void _soundRecorder_PauseResume(object sender, EventArgs e)
        {
            if (_soundRecorder.Paused)
            {
                if (!_pauseFlash)
                {
                    ButtonFlash.Add(pauseButton, pauseButton.ForeColor, Color.Black);
                    _pauseFlash = true;
                }
            }
            else
            {
                if (_pauseFlash)
                {
                    ButtonFlash.Remove(pauseButton);
                    _pauseFlash = false;
                }
            }
        }

        // Update time counter display
        void _soundRecorder_PositionChanged(object sender, EventArgs e)
        {
            recCounterLabel.Text = _soundRecorder.Position.ToString().Substring(0, 8);
        }

        // Save recording (event fires when recording has stopped and recording length > 0)
        void _soundRecorder_SaveRequest(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog
            {
                Title = "Save Sound Recording",
                FileName = "SoundRecording.wav",
                DefaultExt = ".wav",
                AddExtension = true
            };

            if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
            {
                // pass on filename to soundPlayer
                if (_soundRecorder.Save(saveFileDialog1.FileName, false) == NO_ERROR && _soundPlayer.UseLastRecording)
                {
                    _soundPlayer.PlayFile = saveFileDialog1.FileName;
                }
            }
            saveFileDialog1.Dispose();
        }

        // Show single (mono channel) or double (stereo channel) peak meter
        private void _soundRecorder_RecorderChannelsChanged(object sender, EventArgs e)
        {
            SetInputLevelMeter();
        }

        // 8 or 16-bits peak meter
        private void _soundRecorder_RecorderBitsChanged(object sender, EventArgs e)
        {
            SetInputLevelMeter();
        }

        // Show audio input peak level
        internal void _soundRecorder_RecorderInputLevelChanged(object sender, InputLevelEventArgs e)
        {
            _leftLevel = e.LeftLevel;
            leftLevelPanel.Invalidate();

            if (_levelChannels == Channels.Stereo)
            {
                _rightLevel = e.RightLevel;
                rightLevelPanel.Invalidate();
            }
        }

        // Input device changed - (re)set event handlers
        private void _soundRecorder_RecorderInputDeviceChanged(object sender, EventArgs e)
        {
            // (re) set eventhandlers
            _soundRecorder.Events.RecorderInputLevelChanged -= _soundRecorder_RecorderInputLevelChanged;
            _soundRecorder.Events.RecorderInputLevelChanged += _soundRecorder_RecorderInputLevelChanged;
        }

        #endregion

        // ******************************** Drag Borderless Form

        #region Drag Borderless Form

        private const int WM_NCLBUTTONDOWN = 0xA1;
        private const int HT_CAPTION = 0x2;
        private void Control_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                //this.Cursor = Cursors.SizeAll;
                ((Control)sender).Capture = false;
                Message msg = Message.Create(Handle, WM_NCLBUTTONDOWN, (IntPtr)HT_CAPTION, IntPtr.Zero);
                WndProc(ref msg);
                //this.Cursor = Cursors.Default;
            }
        }

        #endregion

        // ******************************** Menu

        #region Menu

        private void SelectDeviceMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ToolStripDropDown menu = (ToolStripDropDown)sender;
            menu.Items.Clear();

            string[] devices = _soundRecorder.InputDevice.GetDevices();
            if (devices.Length > 0)
            {
                int index = _soundRecorder.InputDevice.Index;
                for (int i = 0; i < devices.Length; i++)
                {
                    menu.Items.Add(devices[i]);
                    if (i == index) ((ToolStripMenuItem)menu.Items[i]).Checked = true;
                }
            }
            else
            {
                menu.Items.Add("(No Input Devices)");
            }
        }

        private void SelectDeviceMenuItem_Click(object sender, EventArgs e)
        {
            if (_soundRecorder.InputDevice.Count == 0) adjustDevicesMenuItem.PerformClick();
        }

        private void SelectDeviceMenuDropDown_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (_soundRecorder.InputDevice.Count == 0)
            {
                _soundRecorder.ShowAudioInputPanel(this);
            }
            else
            {
                _soundRecorder.InputDevice.Index = selectDeviceMenuItem.DropDown.Items.IndexOf(e.ClickedItem);
            }
        }

        private void AdjustDevicesMenuItem_Click(object sender, EventArgs e)
        {
            _soundRecorder.ShowAudioInputPanel(this);
        }

        // Channels menu
        private void MonoMenuItem_Click(object sender, EventArgs e)
        {
            monoMenuItem.Checked = true;
            stereoMenuItem.Checked = false;
            _soundRecorder.Channels = Channels.Mono;
        }

        private void StereoMenuItem_Click(object sender, EventArgs e)
        {
            monoMenuItem.Checked = false;
            stereoMenuItem.Checked = true;
            _soundRecorder.Channels = Channels.Stereo;
        }

        // Bits menu
        private void Bits8MenuItem_Click(object sender, EventArgs e)
        {
            HandleBitsMenu(bits8MenuItem, Bits.Bits_08);
        }

        private void Bits16MenuItem_Click(object sender, EventArgs e)
        {
            HandleBitsMenu(bits16MenuItem, Bits.Bits_16);
        }

        private void Bits24MenuItem_Click(object sender, EventArgs e)
        {
            HandleBitsMenu(bits24MenuItem, Bits.Bits_24);
        }

        private void HandleBitsMenu(ToolStripMenuItem item, Bits bits)
        {
            MainWindow.CheckMenuItems(item.Owner, item);
            _soundRecorder.Bits = bits;
        }

        // Sample Rate menu
        private void Hz11025MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz11025MenuItem, SampleRate.Samples_11025);
        }

        private void Hz22050MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz22050MenuItem, SampleRate.Samples_22050);
        }

        private void Hz44100MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz44100MenuItem, SampleRate.Samples_44100);
        }

        private void Hz48000MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz48000MenuItem, SampleRate.Samples_48000);
        }

        private void Hz64000MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz64000MenuItem, SampleRate.Samples_64000);
        }

        private void Hz96000MenuItem_Click(object sender, EventArgs e)
        {
            HandleSampleRateMenu(hz96000MenuItem, SampleRate.Samples_96000);
        }

        private void HandleSampleRateMenu(ToolStripMenuItem item, SampleRate rate)
        {
            MainWindow.CheckMenuItems(item.Owner, item);
            _soundRecorder.SampleRate = rate;
        }

        // Peak meter color
        private void PeakMeterColorMenuItem_Click(object sender, EventArgs e)
        {
            SetLevelMeterColor();
        }

        // Close menu
        private void CloseMenuItem_Click(object sender, EventArgs e)
        {
            _soundRecorder.Stop();
            _soundRecorder.Paused = false;
            Hide();

            _baseForm.SetRecorderMenuItems();
        }

        #endregion

        // ******************************** Record, Pause and Stop Buttons

        #region Record, Pause and Stop Buttons

        // record button
        private void RecordButton_Click(object sender, EventArgs e)
        {
            if (_soundRecorder.Recording) _soundRecorder.Stop();
            else
            {
                _soundRecorder.Record();
                if (_soundRecorder.LastError) ShowErrorMessage(_soundRecorder.LastErrorCode);
            }
        }

        // pause button
        private void PauseButton_Click(object sender, EventArgs e)
        {
            _soundRecorder.Paused = !_soundRecorder.Paused;
        }

        // stop button
        private void StopButton_Click(object sender, EventArgs e)
        {
            _soundRecorder.Stop();
        }

        #endregion

        // ******************************** Input Level Meter

        #region Input Level Meter

        private void SetInputLevelMeter()
        {
            // one or two meters
            if (_soundRecorder.Channels != _levelChannels)
            {
                _levelChannels = _soundRecorder.Channels;
                _levelBits = _soundRecorder.Bits;
                if (_levelChannels == Channels.Stereo)
                {
                    leftLevelPanel.Width = rightLevelPanel.Width = 51;
                    _levelUnits = 51.0F / 32767;
                    rightLevelPanel.Paint += RightLevelPanel_Paint;
                    rightLevelPanel.Visible = true;

                }
                else
                {
                    rightLevelPanel.Visible = false;
                    rightLevelPanel.Paint -= RightLevelPanel_Paint;
                    leftLevelPanel.Width = 104;
                    _levelUnits = 104.0F / 32767;
                }
            }
            else if (_soundRecorder.Bits != _levelBits)
            {
                _levelBits = _soundRecorder.Bits;
                if (_levelChannels == Channels.Stereo) _levelUnits = 51.0F / 32767;
                else _levelUnits = 104.0F / 32767;
            }
        }

        private void LeftLevelPanel_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(_levelBrush, 0, 0, (int)(_levelUnits * _leftLevel), leftLevelPanel.ClientRectangle.Height);
        }

        private void RightLevelPanel_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(_levelBrush, 0, 0, (int)(_levelUnits * _rightLevel), rightLevelPanel.ClientRectangle.Height);
        }

        private void LevelMeterPanel_Click(object sender, EventArgs e)
        {
            SetLevelMeterColor();
        }

        private void SetLevelMeterColor()
        {
            ColorDialog dlg = new ColorDialog();
            dlg.Color = _levelBrush.Color;
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                _levelBrush.Color = dlg.Color;
                MainWindow.Prefs.RecorderLevelMeterColor = dlg.Color;
            }
            dlg.Dispose();
        }

        #endregion

        // ******************************** Close Recorder (Stop and Reset Pause (from Main Form))

        #region Close Recorder

        internal void CloseRecorder()
        {
            _soundRecorder.Stop();
            _soundRecorder.Paused = false;
        }

        #endregion

        // ******************************** Error and Warning Message Dialog

        #region Error and Warning Message Dialog

        private void ShowErrorMessage(int errCode)
        {
            string errorText = errCode == WARNING_FILESIZE ? "Please Note:\r\nHigh quality recording may result in very large file sizes." : _soundRecorder.GetErrorString(errCode);
            if (errCode == WARNING_MICROPHONE) errorText += "\r\n\r\nPlease select an input device using the Sound Recorder's 'Select Device' or 'Adjust Devices' menu item.";

            ErrorDialog errorDialog = new ErrorDialog(MainWindow.APPLICATION_NAME, "SOUND RECORDER\r\n\r\n" + errorText, false);
            errorDialog.checkBox1.Hide();
            errorDialog.checkBox2.Hide();

            _baseForm.CenterDialog(this, errorDialog);
            errorDialog.ShowDialog();

            errorDialog.Dispose();
        }

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Peter Vegter
United States United States
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190425.1 | Last Updated 7 Aug 2018
Article Copyright 2010 by Peter Vegter
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid