Please make me a C# Unity Editor Window script for the referenced class below, I want it to be able to show a centered logo that respects the width of the window and under the logo I want you to provide me the ability to change all the parameters from the class with the ui of the script. I want to be able to select the output folder that the resulting generation will be saved in inside the unity editor, I also want 'Prompt' 'Lyrics' inputfields to be multiline enabled for better user experience. I want there to be a 'GENERATE SONG' button at the bottom of the script that will start the inference. Once inference is complete I want the resulting file to save into the selected asset folder (I want user to drag and drop their folder into it, not have some kind of folder select button with file open browser). Once saved I want to be able to play the resulting file inside of the scripts window. I want the window to be accessed via 'Tools > AceStep'. Also one more thing I need the script to be able to point to the saved file in the unity asset browser that way people can easily find their generations, I also need you to pull the logo from Resources. Don't make the generation automatically play after it's generated but give the user a play button and trackbar slider and stop button. This is a unity Editor Window script no need for gameobjects and all that.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

[Serializable]
public class ACEStepInput
{
    public string checkpoint_path;
    public bool bf16 = true;
    public bool torch_compile = false;
    public int device_id = 0;
    public string output_path; // optional
    public float audio_duration;
    public string prompt;
    public string lyrics;
    public int infer_step;
    public float guidance_scale;
    public string scheduler_type;
    public string cfg_type;
    public float omega_scale;
    public List<int> actual_seeds;
    public float guidance_interval;
    public float guidance_interval_decay;
    public float min_guidance_scale;
    public bool use_erg_tag;
    public bool use_erg_lyric;
    public bool use_erg_diffusion;
    public List<int> oss_steps;
    public float guidance_scale_text = 0.0f;
    public float guidance_scale_lyric = 0.0f;
}

[Serializable]
public class ACEStepOutput
{
    public string status;
    public string output_path;
    public string message;
}

public class ACEStepClient : MonoBehaviour
{
    // URL of your running FastAPI Uvicorn server
    // Make sure this matches your actual server address and port
    private const string serverUrl = "http://localhost:8000/generate";

    /// <summary>
    /// Starts the inference request coroutine.
    /// </summary>
    /// <param name="input">Input data object to send.</param>
    /// <param name="onSuccess">Action on success with output data.</param>
    /// <param name="onError">Action on error with error message.</param>
    public void GenerateAudio(ACEStepInput input, Action<ACEStepOutput> onSuccess, Action<string> onError)
    {
        StartCoroutine(GenerateAudioRoutine(input, onSuccess, onError));
    }

    private IEnumerator GenerateAudioRoutine(ACEStepInput input, Action<ACEStepOutput> onSuccess, Action<string> onError)
    {
        string jsonData = JsonUtility.ToJson(input);
        byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);

        using (UnityWebRequest request = new UnityWebRequest(serverUrl, "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");

            yield return request.SendWebRequest();

#if UNITY_2020_1_OR_NEWER
            bool isNetworkError = request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError;
#else
            bool isNetworkError = request.isNetworkError || request.isHttpError;
#endif

            if (isNetworkError)
            {
                Debug.LogError($"Error sending request: {request.error}");
                onError?.Invoke(request.error);
            }
            else
            {
                try
                {
                    // Parse JSON response
                    ACEStepOutput output = JsonUtility.FromJson<ACEStepOutput>(request.downloadHandler.text);
                    if (output.status == "success")
                    {
                        onSuccess?.Invoke(output);
                    }
                    else
                    {
                        onError?.Invoke($"Server returned error: {output.message}");
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError($"Error parsing response JSON: {e.Message}");
                    onError?.Invoke($"Error parsing response: {e.Message}");
                }
            }
        }
    }
}