hi please fix my script nothing is wrong with it but I don't know why every recording is set to 30 seconds if the recording is under 30 seconds avoid this at all costs and return entire script fixed tysm.

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;

    // Hidden AudioSource for playback control in EditorWindow
    private AudioSource editorAudioSource;

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

    private bool isRecordingSource = false;
    private bool isRecordingReference = false;

    private AudioClip recordingClipSource;
    private AudioClip recordingClipReference;

    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();

        if (editorAudioSource != null && editorAudioSource.gameObject != null)
            DestroyImmediate(editorAudioSource.gameObject);
    }

    private void EditorUpdate()
    {
        if (isPlaying && editorAudioSource != null)
        {
            if (!editorAudioSource.isPlaying)
            {
                isPlaying = false;
                Repaint();
            }
            else
            {
                Repaint();
            }
        }
    }

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

        GUILayout.Space(10);

        if (logo != null)
        {
            float maxWidth = position.width;
            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 (Drag & Drop a Folder from Project Window):", EditorStyles.boldLabel);

        EditorGUI.BeginChangeCheck();
        saveFolderAsset = (DefaultAsset)EditorGUILayout.ObjectField(saveFolderAsset, typeof(DefaultAsset), false, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        if (EditorGUI.EndChangeCheck())
        {
            if (saveFolderAsset != null)
            {
                string path = AssetDatabase.GetAssetPath(saveFolderAsset);
                if (!string.IsNullOrEmpty(path) && AssetDatabase.IsValidFolder(path))
                {
                    saveFolderPath = path;
                    statusMessage = $"Save folder set to '{saveFolderPath}'.";
                }
                else
                {
                    statusMessage = "Please drag and drop a folder (not a file).";
                    saveFolderAsset = null;
                    saveFolderPath = null;
                }
            }
            else
            {
                saveFolderPath = null;
            }
        }

        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 drag and drop 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 _);

                if (!saved)
                {
                    statusMessage = "Failed to save the converted file.";
                }
            }
            else
            {
                // statusMessage already set on failure
            }
        }
        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()),
            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";

            string relativeFolderPath = saveFolderPath.TrimEnd('\\', '/');
            string assetPath = $"{relativeFolderPath}/{fileName}";

            string projectRoot = Directory.GetParent(Application.dataPath).FullName;
            string absoluteSavePath = Path.Combine(projectRoot, assetPath.Replace('/', Path.DirectorySeparatorChar));

            string directoryPath = Path.GetDirectoryName(absoluteSavePath);
            if (!Directory.Exists(directoryPath))
                Directory.CreateDirectory(directoryPath);

            File.WriteAllBytes(absoluteSavePath, fileBytes);

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

            AudioImporter importer = AssetImporter.GetAtPath(assetPath) as AudioImporter;
            if (importer != null)
            {
                AudioImporterSampleSettings sampleSettings = importer.defaultSampleSettings;
                sampleSettings.loadType = AudioClipLoadType.DecompressOnLoad;
                sampleSettings.compressionFormat = AudioCompressionFormat.PCM;
                importer.defaultSampleSettings = sampleSettings;
                importer.SaveAndReimport();
            }

            EditorApplication.delayCall += () =>
            {
                AudioClip clip = AssetDatabase.LoadAssetAtPath<AudioClip>(assetPath);
                if (clip == null)
                {
                    Debug.LogWarning($"Failed to load AudioClip at path: {assetPath}");
                    statusMessage = "Failed to load converted audio clip after import.";
                }
                else
                {
                    convertedClip = clip;
                    statusMessage = "File saved successfully. You can play it back below.";
                    EditorGUIUtility.PingObject(convertedClip);
                    Repaint();
                }
            };

            return true;
        }
        catch (Exception ex)
        {
            Debug.LogError("Failed to save file: " + ex);
            statusMessage = "Failed to save file: " + ex.Message;
            return false;
        }
    }

    private AudioSource GetEditorAudioSource()
    {
        const string objName = "SeedVCEditorAudioSource";
        GameObject go = GameObject.Find(objName);
        if (go == null)
        {
            go = new GameObject(objName);
            go.hideFlags = HideFlags.HideAndDontSave;
            editorAudioSource = go.AddComponent<AudioSource>();
            editorAudioSource.playOnAwake = false;
        }
        else
        {
            editorAudioSource = go.GetComponent<AudioSource>();
            if (editorAudioSource == null)
                editorAudioSource = go.AddComponent<AudioSource>();
        }
        return editorAudioSource;
    }

    private void PlayConvertedClip()
    {
        if (convertedClip == null)
        {
            statusMessage = "Converted clip is not ready to play yet.";
            Debug.LogWarning(statusMessage);
            return;
        }

        AudioSource source = GetEditorAudioSource();

        if (source.isPlaying)
            source.Stop();

        source.clip = convertedClip;
        source.time = 0f;
        source.Play();

        isPlaying = true;
    }

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

        AudioSource source = GetEditorAudioSource();
        source.Stop();
        isPlaying = false;
    }


    #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;
    }

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