Search code examples
c#wpfformswavaudio-recording

How to record WAV in c# WPF?


I can get this code to work in a console application. But I want this to work on a Windows Forms application in c# visual studio 2010. Here is my code:

public partial class MainWindow : Window
{
[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);

...

private void buttonRecordWAV_click(object sender, RoutedEventArgs e)
    {
        mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
        mciSendString("record recsound", "", 0, 0);
        Console.WriteLine("recording, press Enter to stop and save ...");
        Console.ReadLine();
        if (System.Windows.Forms.MessageBox.Show("recording, press OK to stop recording and save", "Recording...", MessageBoxButtons.OK) == System.Windows.Forms.DialogResult.OK)
            {
                System.Windows.Forms.MessageBox.Show("you entered the if statement");
                mciSendString("save recsound result.wav", "", 0, 0);
                mciSendString("close recsound ", "", 0, 0);
            }

    }

However, when I execute this, I don't see any 'result.wav' file in the bin/Debug folder. When I run this code on a console application, it works, and I can see a 'result.wav' in the bin/Debug folder and when I play that file, I hear what ever I recorded. Anybody know how to make this work in the C# Forms Application? Thanks.


Solution

  • You have a strange mixture of technologies going on in your sample code. As you are using Console.ReadLine in an application that has a form as a front end. You are also using System.Windows.Forms.MessageBox which is a winforms class, not a WPF class, here you should be using System.Windows.MessageBox.

    I just put a quick same together however using snippets from your example and it works for me. Sample as follows; markup:

    <Grid>
        <Button x:Name="buttonRecordWav" Click="buttonRecordWav_Click">Start Recording</Button>
    </Grid>
    

    And in the code behind:

    public enum MCIErrors
    {
        NO_ERROR = 0,
        MCIERR_BASE = 256,
        MCIERR_INVALID_DEVICE_ID = 257,
        MCIERR_UNRECOGNIZED_KEYWORD = 259,
        MCIERR_UNRECOGNIZED_COMMAND = 261,
        MCIERR_HARDWARE = 262,
        MCIERR_INVALID_DEVICE_NAME = 263,
        MCIERR_OUT_OF_MEMORY = 264,
        MCIERR_DEVICE_OPEN = 265,
        MCIERR_CANNOT_LOAD_DRIVER = 266,
        MCIERR_MISSING_COMMAND_STRING = 267,
        MCIERR_PARAM_OVERFLOW = 268,
        MCIERR_MISSING_STRING_ARGUMENT = 269,
        MCIERR_BAD_INTEGER = 270,
        MCIERR_PARSER_INTERNAL = 271,
        MCIERR_DRIVER_INTERNAL = 272,
        MCIERR_MISSING_PARAMETER = 273,
        MCIERR_UNSUPPORTED_FUNCTION = 274,
        MCIERR_FILE_NOT_FOUND = 275,
        MCIERR_DEVICE_NOT_READY = 276,
        MCIERR_INTERNAL = 277,
        MCIERR_DRIVER = 278,
        MCIERR_CANNOT_USE_ALL = 279,
        MCIERR_MULTIPLE = 280,
        MCIERR_EXTENSION_NOT_FOUND = 281,
        MCIERR_OUTOFRANGE = 282,
        MCIERR_FLAGS_NOT_COMPATIBLE = 283,
        MCIERR_FILE_NOT_SAVED = 286,
        MCIERR_DEVICE_TYPE_REQUIRED = 287,
        MCIERR_DEVICE_LOCKED = 288,
        MCIERR_DUPLICATE_ALIAS = 289,
        MCIERR_BAD_CONSTANT = 290,
        MCIERR_MUST_USE_SHAREABLE = 291,
        MCIERR_MISSING_DEVICE_NAME = 292,
        MCIERR_BAD_TIME_FORMAT = 293,
        MCIERR_NO_CLOSING_QUOTE = 294,
        MCIERR_DUPLICATE_FLAGS = 295,
        MCIERR_INVALID_FILE = 296,
        MCIERR_NULL_PARAMETER_BLOCK = 297,
        MCIERR_UNNAMED_RESOURCE = 298,
        MCIERR_NEW_REQUIRES_ALIAS = 299,
        MCIERR_NOTIFY_ON_AUTO_OPEN = 300,
        MCIERR_NO_ELEMENT_ALLOWED = 301,
        MCIERR_NONAPPLICABLE_FUNCTION = 302,
        MCIERR_ILLEGAL_FOR_AUTO_OPEN = 303,
        MCIERR_FILENAME_REQUIRED = 304,
        MCIERR_EXTRA_CHARACTERS = 305,
        MCIERR_DEVICE_NOT_INSTALLED = 306,
        MCIERR_GET_CD = 307,
        MCIERR_SET_CD = 308,
        MCIERR_SET_DRIVE = 309,
        MCIERR_DEVICE_LENGTH = 310,
        MCIERR_DEVICE_ORD_LENGTH = 311,
        MCIERR_NO_INTEGER = 312,
        MCIERR_WAVE_OUTPUTSINUSE = 320,
        MCIERR_WAVE_SETOUTPUTINUSE = 321,
        MCIERR_WAVE_INPUTSINUSE = 322,
        MCIERR_WAVE_SETINPUTINUSE = 323,
        MCIERR_WAVE_OUTPUTUNSPECIFIED = 324,
        MCIERR_WAVE_INPUTUNSPECIFIED = 325,
        MCIERR_WAVE_OUTPUTSUNSUITABLE = 326,
        MCIERR_WAVE_SETOUTPUTUNSUITABLE = 327,
        MCIERR_WAVE_INPUTSUNSUITABLE = 328,
        MCIERR_WAVE_SETINPUTUNSUITABLE = 329,
        MCIERR_SEQ_DIV_INCOMPATIBLE = 336,
        MCIERR_SEQ_PORT_INUSE = 337,
        MCIERR_SEQ_PORT_NONEXISTENT = 338,
        MCIERR_SEQ_PORT_MAPNODEVICE = 339,
        MCIERR_SEQ_PORT_MISCERROR = 340,
        MCIERR_SEQ_TIMER = 341,
        MCIERR_SEQ_PORTUNSPECIFIED = 342,
        MCIERR_SEQ_NOMIDIPRESENT = 343,
        MCIERR_NO_WINDOW = 346,
        MCIERR_CREATEWINDOW = 347,
        MCIERR_FILE_READ = 348,
        MCIERR_FILE_WRITE = 349,
        MCIERR_CUSTOM_DRIVER_BASE = 512
    };
    
    [DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
    
    private bool _recording = false;
    
    private void buttonRecordWav_Click(object sender, RoutedEventArgs e)
    {            
        MCIErrors result;
        if (!_recording)
        {
            result = (MCIErrors)mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
            if (result != MCIErrors.NO_ERROR)
            {
                MessageBox.Show("Error code: " + result.ToString());
                return;
            }
            result = (MCIErrors)mciSendString("record recsound", "", 0, 0);
            if (result != MCIErrors.NO_ERROR)
            {
                MessageBox.Show("Error code: " + result.ToString());
                return;
            }
            buttonRecordWav.Content = "Stop Recording";
            _recording = true;
        }
        else
        {
            result = (MCIErrors)mciSendString("save recsound result.wav", "", 0, 0);
            if (result != MCIErrors.NO_ERROR)
            {
                 MessageBox.Show("Error code: " + result.ToString());
                 return;
            }
            result = (MCIErrors)mciSendString("close recsound ", "", 0, 0);
            if (result != MCIErrors.NO_ERROR)
            {
                MessageBox.Show("Error code: " + result.ToString());
                return;
            }
            buttonRecordWav.Content = "Start Recording";
            _recording = false;
        }                            
    }
    

    If I run that, I get the wav file created as expected. Documentation on the mciSendString method here:

    mciSendString function