hi please fix my unity editor window script, it works fine but the resulting file is not saved in the 'Save Folder' location and the playback isn't working. I've also made some comments where things are missing from the UI that I want in it. Please fix the script and provide the script fixed also save tokens by not explaining, please do a complete job.

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;

    // 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, 600);
    }

    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; // 20 pixels padding
            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("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)
                {
                    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.";
                }
            }
            else
            {
                statusMessage = "Conversion failed or no file returned.";
            }
        }
        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", "1.0"), // This is missing from the UI.
            new MultipartFormDataSection("inference_cfg_rate", "0.7"), // This is missing from the UI.
            new MultipartFormDataSection("auto_f0_adjust", "true"), // This is missing from the UI, there should be a checkbox for this.
            new MultipartFormDataSection("pitch_shift", "0") // This is missing from the UI.
        };

        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";
            string fullPath = Path.Combine(saveFolderPath, fileName);

            string absolutePath = Path.Combine(Application.dataPath.Substring(0, Application.dataPath.Length - 6), fullPath);

            File.WriteAllBytes(absolutePath, fileBytes);

            AssetDatabase.ImportAsset(fullPath, ImportAssetOptions.ForceUpdate);

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

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

            return true;
        }
        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]);
        // fallback if samplePos too small (usually 0 right after Stop)
        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;
    }
}