hi please fix my script the Saved Folder only works when I use the select folder button of which I don't even need, I want you to remove it and just let the user drag and drop a asset folder in there. Also it seems playback of the resulting file isn't working still please fix all issues and return back the script fixed, this is for Unity.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;

public class SeedVCWindow : EditorWindow
{
    private Texture2D logo;

    // Parameters (matching AudioConverter class)
    private string serverUrl = "http://localhost:8000/convert";
    private int qualityValue = 10;

    // Additional UI parameters
    private float lengthAdjust = 1.0f;
    private float inferenceCfgRate = 0.7f;
    private bool autoF0Adjust = true;
    private int pitchShift = 0;

    // Audio clips for input
    private AudioClip sourceClip;
    private AudioClip referenceClip;

    // Selected folder to save result
    private DefaultAsset saveFolderAsset;
    private string saveFolderPath = "Assets";

    // Status message
    private string statusMessage;
    private bool isConverting = false;

    // Playback
    private AudioClip convertedClip;
    private bool isPlaying = false;
    private Vector2 scrollPos;

    // --- Added for Recording ---
    private string[] micDevices;
    private int selectedMicIndex = 0;

    // Recording state
    private bool isRecordingSource = false;
    private bool isRecordingReference = false;

    private AudioClip recordingClipSource;
    private AudioClip recordingClipReference;

    // Max recording length in seconds
    private const int maxRecordingLength = 30;
    private const int defaultSampleRate = 44100;

    [MenuItem("Tools/Seed_VC")]
    private static void ShowWindow()
    {
        var window = GetWindow<SeedVCWindow>("Seed_VC");
        window.minSize = new Vector2(400, 640);
    }

    private void OnEnable()
    {
        logo = Resources.Load<Texture2D>("seed_vc_logo");
        EditorApplication.update += EditorUpdate;

        micDevices = Microphone.devices;
        if (micDevices == null || micDevices.Length == 0)
        {
            micDevices = new string[] { "No Microphone Devices Found" };
            selectedMicIndex = 0;
        }
        else
        {
            selectedMicIndex = 0;
        }
    }

    private void OnDisable()
    {
        EditorApplication.update -= EditorUpdate;
        StopPlayback();
        StopRecordingSource();
        StopRecordingReference();
    }

    private void EditorUpdate()
    {
        if (isPlaying && !EditorApplication.isPlaying && !Application.isPlaying)
        {
            Repaint();
        }
    }

    private void OnGUI()
    {
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

        GUILayout.Space(10);

        if (logo != null)
        {
            float maxWidth = position.width; // no extra padding needed
            float aspectRatio = (float)logo.height / logo.width;
            float drawWidth = Mathf.Min(logo.width, maxWidth);
            float drawHeight = drawWidth * aspectRatio;

            float posX = (position.width - drawWidth) / 2f;
            Rect rect = GUILayoutUtility.GetRect(drawWidth, drawHeight);
            rect.x = posX;

            GUI.DrawTexture(rect, logo, ScaleMode.ScaleToFit);
        }
        else
        {
            EditorGUILayout.HelpBox("Logo not found in Resources as 'seed_vc_logo'. Please add a PNG named 'seed_vc_logo' to Assets/Resources.", MessageType.Warning);
        }

        GUILayout.Space(10);

        EditorGUILayout.LabelField("Server URL:", EditorStyles.boldLabel);
        serverUrl = EditorGUILayout.TextField(serverUrl);

        EditorGUILayout.LabelField("Quality Value (diffusion_steps):", EditorStyles.boldLabel);
        qualityValue = EditorGUILayout.IntSlider(qualityValue, 1, 100);

        GUILayout.Space(10);

        EditorGUILayout.LabelField("Additional Conversion Parameters:", EditorStyles.boldLabel);
        lengthAdjust = EditorGUILayout.Slider("Length Adjust", lengthAdjust, 0.1f, 3f);
        inferenceCfgRate = EditorGUILayout.Slider("Inference CFG Rate", inferenceCfgRate, 0f, 1f);
        autoF0Adjust = EditorGUILayout.Toggle("Auto F0 Adjust", autoF0Adjust);
        pitchShift = EditorGUILayout.IntSlider("Pitch Shift", pitchShift, -12, 12);

        GUILayout.Space(10);

        EditorGUILayout.LabelField("Select Recording Device (Microphone):", EditorStyles.boldLabel);

        if (micDevices.Length == 0 || micDevices[0] == "No Microphone Devices Found")
        {
            EditorGUILayout.HelpBox("No microphone devices found on this machine.", MessageType.Warning);
        }
        else
        {
            int newSelectedIndex = EditorGUILayout.Popup(selectedMicIndex, micDevices);
            if (newSelectedIndex != selectedMicIndex)
            {
                selectedMicIndex = newSelectedIndex;
                if (isRecordingSource) StopRecordingSource();
                if (isRecordingReference) StopRecordingReference();
            }
        }

        GUILayout.Space(10);

        EditorGUILayout.LabelField("Source Audio Clip:", EditorStyles.boldLabel);
        EditorGUILayout.BeginHorizontal();
        sourceClip = (AudioClip)EditorGUILayout.ObjectField(sourceClip, typeof(AudioClip), false);

        if (micDevices.Length > 0 && micDevices[0] != "No Microphone Devices Found")
        {
            if (!isRecordingSource)
            {
                if (GUILayout.Button("Record Source", GUILayout.Width(120)))
                {
                    StartRecordingSource();
                }
            }
            else
            {
                if (GUILayout.Button("Stop Recording", GUILayout.Width(120)))
                {
                    StopRecordingSource();
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.LabelField("Reference Audio Clip:", EditorStyles.boldLabel);
        EditorGUILayout.BeginHorizontal();
        referenceClip = (AudioClip)EditorGUILayout.ObjectField(referenceClip, typeof(AudioClip), false);

        if (micDevices.Length > 0 && micDevices[0] != "No Microphone Devices Found")
        {
            if (!isRecordingReference)
            {
                if (GUILayout.Button("Record Reference", GUILayout.Width(120)))
                {
                    StartRecordingReference();
                }
            }
            else
            {
                if (GUILayout.Button("Stop Recording", GUILayout.Width(120)))
                {
                    StopRecordingReference();
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(10);

        EditorGUILayout.LabelField("Save Folder:", EditorStyles.boldLabel);
        EditorGUILayout.BeginHorizontal();

        saveFolderAsset = (DefaultAsset)EditorGUILayout.ObjectField(saveFolderAsset, typeof(DefaultAsset), false);
        if (GUILayout.Button("Select Folder", GUILayout.Width(100)))
        {
            string selectedPath = EditorUtility.OpenFolderPanel("Select Save Folder", Application.dataPath, "");
            if (!string.IsNullOrEmpty(selectedPath))
            {
                if (selectedPath.StartsWith(Application.dataPath))
                {
                    saveFolderPath = "Assets" + selectedPath.Substring(Application.dataPath.Length);
                    saveFolderAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(saveFolderPath);
                }
                else
                {
                    EditorUtility.DisplayDialog("Invalid Folder", "Selected folder must be inside the Assets directory.", "OK");
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(15);

        GUI.enabled = !isConverting;
        if (GUILayout.Button("CONVERT", GUILayout.Height(40)))
        {
            if (!ValidateInputs())
                return;

            _ = ConvertAudioFiles();
        }
        GUI.enabled = true;

        GUILayout.Space(10);

        EditorGUILayout.HelpBox(statusMessage, MessageType.Info);

        GUILayout.Space(10);

        if (convertedClip != null)
        {
            EditorGUILayout.LabelField("Converted Audio Playback:", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();

            if (!isPlaying)
            {
                if (GUILayout.Button("Play"))
                {
                    PlayConvertedClip();
                }
            }
            else
            {
                if (GUILayout.Button("Stop"))
                {
                    StopPlayback();
                }
            }

            if (GUILayout.Button("Ping Asset", GUILayout.Width(100)))
            {
                string path = AssetDatabase.GetAssetPath(convertedClip);
                if (!string.IsNullOrEmpty(path))
                {
                    UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<AudioClip>(path);
                    if (obj != null) EditorGUIUtility.PingObject(obj);
                }
            }
            EditorGUILayout.EndHorizontal();
        }

        EditorGUILayout.EndScrollView();
    }

    private bool ValidateInputs()
    {
        if (string.IsNullOrWhiteSpace(serverUrl))
        {
            statusMessage = "Server URL cannot be empty.";
            return false;
        }
        if (qualityValue < 1)
        {
            statusMessage = "Quality value must be greater than 0.";
            return false;
        }
        if (sourceClip == null)
        {
            statusMessage = "Please assign a Source Audio Clip.";
            return false;
        }
        if (referenceClip == null)
        {
            statusMessage = "Please assign a Reference Audio Clip.";
            return false;
        }
        if (saveFolderAsset == null || string.IsNullOrEmpty(saveFolderPath))
        {
            statusMessage = "Please select a save folder inside the Assets directory.";
            return false;
        }
        return true;
    }

    private async Task ConvertAudioFiles()
    {
        isConverting = true;
        statusMessage = "Reading audio clips and preparing data...";
        Repaint();

        convertedClip = null;
        StopPlayback();

        try
        {
            byte[] sourceWavData = AudioClipToWav(sourceClip);
            byte[] referenceWavData = AudioClipToWav(referenceClip);

            if (sourceWavData == null || referenceWavData == null)
            {
                statusMessage = "Failed to convert AudioClips to WAV bytes.";
                isConverting = false;
                Repaint();
                return;
            }

            statusMessage = "Sending data to server...";
            Repaint();

            var base64FileData = await UploadAudioAndConvert(sourceWavData, referenceWavData);

            if (!string.IsNullOrEmpty(base64FileData))
            {
                statusMessage = $"Conversion succeeded, saving the file...";
                Repaint();

                bool saved = SaveFileToAssetFolder(base64FileData, out AudioClip loadedClip);

                if (saved && loadedClip != null)
                {
                    convertedClip = loadedClip;
                    statusMessage = "File saved successfully. You can play it back below.";
                    EditorGUIUtility.PingObject(convertedClip);
                }
                else
                {
                    statusMessage = "Failed to save the file as an asset or load it.";
                }
            }
            else
            {
                // statusMessage already set in function for failures
            }
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
            statusMessage = $"An error occurred: {ex.Message}";
        }
        finally
        {
            isConverting = false;
            Repaint();
        }
    }

    private async Task<string> UploadAudioAndConvert(byte[] sourceAudioBytes, byte[] referenceAudioBytes)
    {
        List<IMultipartFormSection> formData = new List<IMultipartFormSection>
        {
            new MultipartFormFileSection("source_file", sourceAudioBytes, "source.wav", "audio/wav"),
            new MultipartFormFileSection("reference_file", referenceAudioBytes, "reference.wav", "audio/wav"),
            new MultipartFormDataSection("diffusion_steps", qualityValue.ToString()),
            new MultipartFormDataSection("length_adjust", lengthAdjust.ToString("F2")),
            new MultipartFormDataSection("inference_cfg_rate", inferenceCfgRate.ToString("F2")),
            new MultipartFormDataSection("auto_f0_adjust", autoF0Adjust.ToString().ToLower()), // needs to be "true" or "false"
            new MultipartFormDataSection("pitch_shift", pitchShift.ToString())
        };

        using (UnityWebRequest request = UnityWebRequest.Post(serverUrl, formData))
        {
            var operation = request.SendWebRequest();

            while (!operation.isDone)
                await Task.Yield();

#if UNITY_2020_1_OR_NEWER
            if (request.result != UnityWebRequest.Result.Success)
#else
            if (request.isNetworkError || request.isHttpError)
#endif
            {
                statusMessage = $"Server error: {request.error}";
                return null;
            }

            var textResult = request.downloadHandler.text;
            if (string.IsNullOrWhiteSpace(textResult))
            {
                statusMessage = "Server returned an empty response.";
                return null;
            }

            try
            {
                ConversionResponse response = JsonUtility.FromJson<ConversionResponse>(textResult);
                string filePath = response.windows_path ?? response.file_path;

                if (string.IsNullOrEmpty(filePath))
                {
                    statusMessage = "Server response does not contain a valid file path.";
                    return null;
                }

                if (!File.Exists(filePath))
                {
                    statusMessage = $"Returned file does not exist on disk: {filePath}";
                    return null;
                }

                byte[] convertedFileBytes = File.ReadAllBytes(filePath);

                return Convert.ToBase64String(convertedFileBytes);
            }
            catch (Exception ex)
            {
                statusMessage = "Failed to parse server response: " + ex.Message;
                return null;
            }
        }
    }

    private bool SaveFileToAssetFolder(string base64FileData, out AudioClip loadedClip)
    {
        loadedClip = null;
        try
        {
            byte[] fileBytes = Convert.FromBase64String(base64FileData);
            string fileName = $"converted_{DateTime.Now:yyyyMMdd_HHmmss}.wav";

            // Ensure save folder path doesn't end with slash and is relative inside Assets
            string relativeFolderPath = saveFolderPath.TrimEnd('\\', '/');

            string fullAssetPath = $"{relativeFolderPath}/{fileName}";

            string absoluteSavePath = Path.Combine(Application.dataPath.Substring(0, Application.dataPath.Length - 6), fullAssetPath);
            string directoryPath = Path.GetDirectoryName(absoluteSavePath);

            if (!Directory.Exists(directoryPath))
                Directory.CreateDirectory(directoryPath);

            File.WriteAllBytes(absoluteSavePath, fileBytes);

            AssetDatabase.ImportAsset(fullAssetPath, ImportAssetOptions.ForceUpdate);
            AssetDatabase.Refresh();

            loadedClip = AssetDatabase.LoadAssetAtPath<AudioClip>(fullAssetPath);

            if (loadedClip == null)
                Debug.LogWarning("Saved file but failed to load the AudioClip asset after import.");

            return loadedClip != null;
        }
        catch (Exception ex)
        {
            Debug.LogError("Failed to save file: " + ex);
            return false;
        }
    }

    private void PlayConvertedClip()
    {
        if (convertedClip == null)
            return;

        if (isPlaying)
            StopPlayback();

        isPlaying = true;

        PlayClip(convertedClip);
    }

    private void StopPlayback()
    {
        if (!isPlaying)
            return;

        isPlaying = false;

        StopClip(convertedClip);
    }

    private static readonly Type audioUtilType = typeof(AudioImporter).Assembly.GetType("UnityEditor.AudioUtil");
    private static readonly System.Reflection.MethodInfo playClipMethod = audioUtilType?.GetMethod("PlayClip", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[] { typeof(AudioClip) }, null);
    private static readonly System.Reflection.MethodInfo stopClipMethod = audioUtilType?.GetMethod("StopClip", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[] { typeof(AudioClip) }, null);

    private static void PlayClip(AudioClip clip)
    {
        if (clip == null) return;
        playClipMethod?.Invoke(null, new object[] { clip });
    }

    private static void StopClip(AudioClip clip)
    {
        if (clip == null) return;
        stopClipMethod?.Invoke(null, new object[] { clip });
    }

    #region AudioClip to WAV conversion

    private byte[] AudioClipToWav(AudioClip clip)
    {
        if (clip == null)
            return null;

        float[] samples = new float[clip.samples * clip.channels];
        clip.GetData(samples, 0);

        return ConvertAudioClipDataToWav(samples, clip.channels, clip.frequency);
    }

    private byte[] ConvertAudioClipDataToWav(float[] samples, int channels, int sampleRate)
    {
        MemoryStream stream = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(stream);

        int sampleCount = samples.Length;

        writer.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"));
        writer.Write(36 + sampleCount * 2);
        writer.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"));

        writer.Write(System.Text.Encoding.UTF8.GetBytes("fmt "));
        writer.Write(16);
        writer.Write((short)1);
        writer.Write((short)channels);
        writer.Write(sampleRate);
        writer.Write(sampleRate * channels * 2);
        writer.Write((short)(channels * 2));
        writer.Write((short)16);

        writer.Write(System.Text.Encoding.UTF8.GetBytes("data"));
        writer.Write(sampleCount * 2);

        short[] intData = new short[sampleCount];
        for (int i = 0; i < sampleCount; i++)
        {
            float sample = Mathf.Clamp(samples[i], -1f, 1f);
            intData[i] = (short)(sample * short.MaxValue);
        }

        for (int i = 0; i < intData.Length; i++)
            writer.Write(intData[i]);

        writer.Flush();
        writer.Close();

        return stream.ToArray();
    }

    #endregion

    #region Recording Methods

    private void StartRecordingSource()
    {
        if (micDevices == null || micDevices.Length == 0 || micDevices[0] == "No Microphone Devices Found")
        {
            statusMessage = "No microphone device available.";
            return;
        }

        if (isRecordingSource)
            return;

        if (Microphone.IsRecording(micDevices[selectedMicIndex]))
            Microphone.End(micDevices[selectedMicIndex]);

        int minFreq, maxFreq;
        Microphone.GetDeviceCaps(micDevices[selectedMicIndex], out minFreq, out maxFreq);

        int sampleRateToUse = defaultSampleRate;

        if (minFreq != 0 && maxFreq != 0)
        {
            if (defaultSampleRate < minFreq || defaultSampleRate > maxFreq)
            {
                if (minFreq <= 16000 && maxFreq >= 16000)
                    sampleRateToUse = 16000;
                else
                    sampleRateToUse = minFreq;
            }
        }

        try
        {
            recordingClipSource = Microphone.Start(micDevices[selectedMicIndex], false, maxRecordingLength, sampleRateToUse);
            isRecordingSource = true;
            statusMessage = $"Recording Source Audio @ {sampleRateToUse} Hz...";
        }
        catch (Exception ex)
        {
            statusMessage = "Failed to start recording: " + ex.Message;
        }
    }

    private void StopRecordingSource()
    {
        if (!isRecordingSource)
            return;

        Microphone.End(micDevices[selectedMicIndex]);

        int samplePos = Microphone.GetPosition(micDevices[selectedMicIndex]);
        if (samplePos < 100 && recordingClipSource != null)
            samplePos = recordingClipSource.samples;

        if (samplePos > 0 && recordingClipSource != null)
        {
            AudioClip newClip = AudioClip.Create("RecordedSource", samplePos, recordingClipSource.channels, recordingClipSource.frequency, false);
            float[] samples = new float[samplePos * recordingClipSource.channels];
            recordingClipSource.GetData(samples, 0);
            newClip.SetData(samples, 0);

            recordingClipSource = null;
            sourceClip = newClip;
            statusMessage = $"Source recording stopped. Length: {samplePos / (float)newClip.frequency:F2} seconds.";
        }
        else
        {
            statusMessage = "Source recording stopped but no audio data was captured.";
        }

        isRecordingSource = false;
    }

    private void StartRecordingReference()
    {
        if (micDevices == null || micDevices.Length == 0 || micDevices[0] == "No Microphone Devices Found")
        {
            statusMessage = "No microphone device available.";
            return;
        }

        if (isRecordingReference)
            return;

        if (Microphone.IsRecording(micDevices[selectedMicIndex]))
            Microphone.End(micDevices[selectedMicIndex]);

        int minFreq, maxFreq;
        Microphone.GetDeviceCaps(micDevices[selectedMicIndex], out minFreq, out maxFreq);

        int sampleRateToUse = defaultSampleRate;

        if (minFreq != 0 && maxFreq != 0)
        {
            if (defaultSampleRate < minFreq || defaultSampleRate > maxFreq)
            {
                if (minFreq <= 16000 && maxFreq >= 16000)
                    sampleRateToUse = 16000;
                else
                    sampleRateToUse = minFreq;
            }
        }

        try
        {
            recordingClipReference = Microphone.Start(micDevices[selectedMicIndex], false, maxRecordingLength, sampleRateToUse);
            isRecordingReference = true;
            statusMessage = $"Recording Reference Audio @ {sampleRateToUse} Hz...";
        }
        catch (Exception ex)
        {
            statusMessage = "Failed to start recording: " + ex.Message;
        }
    }

    private void StopRecordingReference()
    {
        if (!isRecordingReference)
            return;

        Microphone.End(micDevices[selectedMicIndex]);

        int samplePos = Microphone.GetPosition(micDevices[selectedMicIndex]);
        if (samplePos < 100 && recordingClipReference != null)
            samplePos = recordingClipReference.samples;

        if (samplePos > 0 && recordingClipReference != null)
        {
            AudioClip newClip = AudioClip.Create("RecordedReference", samplePos, recordingClipReference.channels, recordingClipReference.frequency, false);
            float[] samples = new float[samplePos * recordingClipReference.channels];
            recordingClipReference.GetData(samples, 0);
            newClip.SetData(samples, 0);

            recordingClipReference = null;
            referenceClip = newClip;
            statusMessage = $"Reference recording stopped. Length: {samplePos / (float)newClip.frequency:F2} seconds.";
        }
        else
        {
            statusMessage = "Reference recording stopped but no audio data was captured.";
        }

        isRecordingReference = false;
    }

    #endregion

    [Serializable]
    private class ConversionResponse
    {
        public string windows_path;
        public string file_path;
    }
}