Search code examples
c#uwpaudio-recordingwindows-10-iot-core

UWP Windows 10 IoT 2 channel Simultaneous Audio Recording


I would like to know how to record 2 separate audio channel simultaneously. I have 2 USB adapters with mic & speaker respectively.enter image description here The samples code which I can find only support single channel recording at a time. Please help. Thanks.

For single channel my code as follow;

MediaCapture audioCapture = new MediaCapture();
MediaCaptureInitializationSettings captureInitSettings = new MediaCaptureInitializationSettings();

captureInitSettings.StreamingCaptureMode = StreamingCaptureMode.Audio;
captureInitSettings.MediaCategory = MediaCategory.Other;
captureInitSettings.AudioProcessing = AudioProcessing.Default;

await audioCapture.InitializeAsync(captureInitSettings);

private async void recordChannelA()
    {
        StorageFolder externalDevices = KnownFolders.RemovableDevices;
        IReadOnlyList<StorageFolder> externalDrives = await externalDevices.GetFoldersAsync();
        StorageFolder usbStorage = externalDrives[0];

        if (usbStorage != null)
        {
            StorageFolder recordFolder = await usbStorage.CreateFolderAsync(recFolderName, CreationCollisionOption.OpenIfExists);
            await usbStorage.GetFolderAsync(recFolderName);
            StorageFile recordFile = await recordFolder.CreateFileAsync("Recording - " + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".mp3", Windows.Storage.CreationCollisionOption.GenerateUniqueName);

            MediaEncodingProfile profile = null;
            profile = MediaEncodingProfile.CreateM4a(Windows.Media.MediaProperties.AudioEncodingQuality.Auto);
            await audioCapture.StartRecordToStorageFileAsync(profile, recordFile);

            Message.Text = "Recording ... ";

            recordingtimerRun = new TimeSpan(0, 0, 0);
            recordingTimer.Start();
        }
        else Message.Text = "Recording error !";
    }

Update; I created a 'listview' for the enumerated devices and to select the respective capture device. However, there is an Syntax Error which i cannot convert the enumaration.deviceinformation to imediasource.

captureInitSettings.AudioSource = captureDeviceList[audioCaptureList.SelectedIndex];

Update: I managed to get it to work The solution is

    captureInitSettingsA.AudioDeviceId = captureDeviceList[audioCaptureList.SelectedIndex].Id;
captureInitSettingsB.AudioDeviceId = captureDeviceList[audioCaptureList.SelectedIndex].Id;

However, how do i save these selections in app settings .. so that when I reboot I don't have to re-select again.

Update: I manage to save the app setting for audiocapture & audiorender devices but I am not sure how to retrieve them & also to check if there is any previous settings saved.

Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

            localSettings.Values["audioACaptureSettings"] = captureAInitSettings.AudioDeviceId;
            localSettings.Values["audioARenderSettings"] = mediaPlayerA.AudioDevice.Id;
localSettings.Values["audioBCaptureSettings"] = captureBInitSettings.AudioDeviceId;
            localSettings.Values["audioBRenderSettings"] = mediaPlayerB.AudioDevice.Id;



private void loadAudioConfig()
    {
        Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
        Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

        if (localSettings.Values["audioACaptureSettings"] != null)
        {
            captureAInitSettings.AudioDeviceId = localSettings.Values["audioACaptureSettings"].ToString();
        }

        if (localSettings.Values["audioARenderSettings"] != null)
        {
            Object audioARenderValue = localSettings.Values["audioARenderSettings"];
            mediaPlayerA.AudioDevice = audioARenderValue;
        }

        if (localSettings.Values["PAaudioCaptureSettings"] != null)
        {
            captureBInitSettings.AudioDeviceId = localSettings.Values["audioBCaptureSettings"].ToString();
        }

        if (localSettings.Values["PAaudioRenderSettings"] != null)
        {
            Object audioBRenderValue = localSettings.Values["audioBRenderSettings"];
            mediaPlayerB.AudioDevice = audioBRenderValue;
        }

Solution

  • You can refer to this document which introduced how to store and retrieve settings and other app data. You can save the data to Settings and Files. When you use Settings, it only supports multiple data types as mentioned in the document. If use files, you can store binary data or to enable your own, customized serialized types,.

    In your provided code, it is correct to check if there is any previous settings saved:

        if (localSettings.Values["audioACaptureSettings"] != null)
        {
            captureAInitSettings.AudioDeviceId = localSettings.Values["audioACaptureSettings"].ToString();
        }
    

    But it is incorrect about how to retrieve the setting as AudioDevice because it can not implicitly convert string to DeviceInformation. Please try in this way:

        if (localSettings.Values["audioARenderSettings"] != null)
        {
            var aduioSource = localSettings.Values["audioARenderSettings"] as string;
            mediaPlayerA.AudioDevice = await DeviceInformation.CreateFromIdAsync(aduioSource);
        }