using System.IO;
using UnityEngine;

public class AudioClipToWavSaver : MonoBehaviour
{
    /// <summary>
    /// Saves the provided AudioClip as a 16-bit WAV file to the specified path.
    /// On Android, use Application.persistentDataPath for safe write access.
    /// </summary>
    /// <param name="clip">AudioClip to save</param>
    /// <param name="filename">File name including .wav extension</param>
    /// <returns>Full path of saved file</returns>
    public string SaveAudioClipToWav(AudioClip clip, string filename)
    {
        if (clip == null)
        {
            Debug.LogError("SaveAudioClipToWav: AudioClip is null!");
            return null;
        }

        string directory = Application.persistentDataPath;
        if (!Directory.Exists(directory))
            Directory.CreateDirectory(directory);

        string filepath = Path.Combine(directory, filename);

        try
        {
            using (FileStream fileStream = new FileStream(filepath, FileMode.Create))
            {
                ConvertAndWriteWav(clip, fileStream);
            }

            Debug.Log($"WAV file saved to: {filepath}");
            return filepath;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Failed to save WAV file: {e.Message}");
            return null;
        }
    }

    private void ConvertAndWriteWav(AudioClip clip, Stream stream)
    {
        int sampleCount = clip.samples * clip.channels;
        float[] samples = new float[sampleCount];
        clip.GetData(samples, 0);

        int hz = clip.frequency;
        short channels = (short)clip.channels;

        // Convert float samples [-1.0f, 1.0f] to 16-bit PCM data
        byte[] pcmData = new byte[sampleCount * 2]; // 2 bytes per sample for 16-bit

        int pcmIndex = 0;
        for (int i = 0; i < sampleCount; i++)
        {
            short intSample = (short)(Mathf.Clamp(samples[i], -1f, 1f) * short.MaxValue);
            pcmData[pcmIndex++] = (byte)(intSample & 0xFF);
            pcmData[pcmIndex++] = (byte)((intSample >> 8) & 0xFF);
        }

        // Write WAV header
        using (BinaryWriter writer = new BinaryWriter(stream))
        {
            // RIFF header
            writer.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"));
            writer.Write(36 + pcmData.Length); // Chunk size
            writer.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"));

            // fmt subchunk
            writer.Write(System.Text.Encoding.UTF8.GetBytes("fmt "));
            writer.Write(16); // Subchunk1Size for PCM
            writer.Write((short)1); // AudioFormat PCM = 1
            writer.Write(channels);
            writer.Write(hz);
            writer.Write(hz * channels * 2); // Byte rate = SampleRate * NumChannels * BitsPerSample/8
            writer.Write((short)(channels * 2)); // Block align = NumChannels * BitsPerSample/8
            writer.Write((short)16); // Bits per sample

            // data subchunk
            writer.Write(System.Text.Encoding.UTF8.GetBytes("data"));
            writer.Write(pcmData.Length);
            writer.Write(pcmData);
        }
    }

    // Example usage:
    // Attach this script to a GameObject, assign an AudioClip and call SaveExampleClip()
    [Header("Example Usage")]
    public AudioClip audioClipToSave;
    public AudioSource audioSourceToSave;
    public LOADSAVE LS;

    // Call this to save the example clip as "myAudio.wav"
    public void SaveExampleClip()
    {
        string savedPath = SaveAudioClipToWav(audioClipToSave, "myAudio.wav");
        if (!string.IsNullOrEmpty(savedPath))
        {
            Debug.Log($"Saved successfully: {savedPath}");
            LS.SaveFile(savedPath);
        }
    }

    public void Update()
    {
        audioClipToSave = audioSourceToSave.clip;
    }
}

use the above class to either use it or learn from it to fix the audio processing of the next script below because its giving problems on android.

using System.Collections.Generic;
using System.IO;
using TMPro;
using UnityEngine;
using Michsky.UI.Reach;

public class LOADSAVE : MonoBehaviour
{
    public string FinalPath;
    public TMP_InputField AgentName;
    public TMP_InputField AgentPerson;
    public Michsky.UI.Reach.Dropdown SelectedAgent;
    public string RefVoice;
    public TMP_InputField Transcription;
    public FastAPIAudioTranscriber TRANSCRIBER;
    public string baseFolder = string.Empty;
    public string agentFolderName = string.Empty;
    public string agentFolderPath = string.Empty;

    private string wavFileType;

    private AudioClip recordingClip;
    private bool isRecording = false;
    private const int recordingFreq = 44100; // common freq for WAV
    private float maxRecordingDuration = 60f; // seconds

    void Start()
    {
        // Setup persistent base folder + extension for wav files
        baseFolder = Path.Combine(Application.persistentDataPath, "Agent Presets");

        // NativeFilePicker wants extension *without* the dot:
        wavFileType = NativeFilePicker.ConvertExtensionToFileType("wav");
    }

    public void LoadFileVoice()
    {
        NativeFilePicker.PickFile((path) =>
        {
            if (string.IsNullOrEmpty(path))
            {
                Debug.Log("Operation cancelled");
                // TODO: Show cancel UI popup/message if needed
                return;
            }

            Debug.Log($"Selected file: {path}");
            FinalPath = path;
            RefVoice = path;

            try
            {
                // Sanitize and check inputs
                string agentNameText = SanitizeFileName(string.IsNullOrEmpty(AgentName.text) ? "DefaultAgent" : AgentName.text);

                string baseFolderPath = Path.Combine(Application.persistentDataPath, "Agent Presets");
                string agentFolder = Path.Combine(baseFolderPath, agentNameText);

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

                string destFilePath = Path.Combine(agentFolder, "Agent_Voice.wav");

                // Copy the selected WAV file to agent folder
                File.Copy(path, destFilePath, true);

                Debug.Log($"Voice file copied to: {destFilePath}");

                TRANSCRIBER.audioFilePath = destFilePath;

                // TODO: Show UI confirmation popup

            }
            catch (System.Exception ex)
            {
                Debug.LogError($"Failed to copy voice file: {ex.Message}");
                // TODO: Show error UI popup
            }

        }, new string[] { wavFileType });
    }

    /// <summary>
    /// Save a file from a given path to a user selectable export location.
    /// </summary>
    /// <param name="filePath">The full path of the file to be exported</param>
    public void SaveFile(string filePath)
    {
        if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
        {
            Debug.LogError("SaveFile: Input file path is invalid or file does not exist");
            return;
        }

        string tempPath = Path.Combine(Application.temporaryCachePath, "test.wav");

        try
        {
            byte[] bytes = File.ReadAllBytes(filePath);
            File.WriteAllBytes(tempPath, bytes);

            NativeFilePicker.ExportFile(tempPath, (success) =>
            {
                Debug.Log("File export success: " + success);
                // TODO: Show feedback popup depending on success
            });
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"SaveFile: Failed to export file: {ex}");
            // TODO: Show error popup
        }
    }

    public void SaveAgentTranscription()
    {
        try
        {
            string agentNameText = SanitizeFileName(string.IsNullOrEmpty(AgentName.text) ? "DefaultAgent" : AgentName.text);

            string baseFolderPath = Path.Combine(Application.persistentDataPath, "Agent Presets");
            if (!Directory.Exists(baseFolderPath))
                Directory.CreateDirectory(baseFolderPath);

            string agentFolder = Path.Combine(baseFolderPath, agentNameText);
            if (!Directory.Exists(agentFolder))
                Directory.CreateDirectory(agentFolder);

            string filePath = Path.Combine(agentFolder, "Agent_Transcription.txt");

            File.WriteAllText(filePath, Transcription.text);

            Debug.Log($"Transcription saved successfully at: {filePath}");
            // TODO: Show UI confirmation

        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Failed to save transcription: {ex}");
            // TODO: Show error UI popup
        }
    }

    public void SaveFileAgent()
    {
        try
        {
            string agentNameText = SanitizeFileName(string.IsNullOrEmpty(AgentName.text) ? "DefaultAgent" : AgentName.text);

            string baseFolderPath = Path.Combine(Application.persistentDataPath, "Agent Presets");
            if (!Directory.Exists(baseFolderPath))
                Directory.CreateDirectory(baseFolderPath);

            string agentFolder = Path.Combine(baseFolderPath, agentNameText);
            if (!Directory.Exists(agentFolder))
                Directory.CreateDirectory(agentFolder);

            string fileName = SanitizeFileName(agentNameText + "_INFO") + ".txt";
            string filePath = Path.Combine(agentFolder, fileName);

            List<string> lines = new List<string>
            {
                AgentName.text,
                AgentPerson.text,
            };

            File.WriteAllLines(filePath, lines);

            Debug.Log($"Agent info file saved successfully at: {filePath}");
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Failed to save file: {ex}");
            // TODO: Show error UI popup
        }
    }

    public void LoadAgentsInDrop()
    {
        string baseFolderPath = Path.Combine(Application.persistentDataPath, "Agent Presets");

        if (!Directory.Exists(baseFolderPath))
        {
            Debug.LogWarning($"Agent Presets folder does not exist at: {baseFolderPath}");
            return;
        }

        SelectedAgent.items.Clear();

        string[] agentFolders = Directory.GetDirectories(baseFolderPath);

        if (agentFolders.Length == 0)
        {
            Debug.Log("No agent folders found in Agent Presets.");
            return;
        }

        foreach (string folderPath in agentFolders)
        {
            string folderName = Path.GetFileName(folderPath);
            SelectedAgent.CreateNewItem(folderName);
        }
    }

    public void RecordAgentVoice()
    {
        // This is a simple toggle example for recording audio on button press to release

        if (!isRecording)
        {
            if (string.IsNullOrEmpty(AgentName.text))
            {
                Debug.LogWarning("AgentName is empty. Please enter a valid agent name before recording.");
                return;
            }

            Debug.Log("Started recording...");

            // Start microphone recording
            recordingClip = Microphone.Start(null, false, (int)maxRecordingDuration, recordingFreq);
            isRecording = true;
        }
        else
        {
            Debug.Log("Stopped recording.");

            if (!Microphone.IsRecording(null))
            {
                Debug.LogWarning("Microphone is not recording currently.");
                isRecording = false;
                return;
            }

            int length = Microphone.GetPosition(null);
            Microphone.End(null);

            if (length <= 0)
            {
                Debug.LogError("Recorded audio length is 0.");
                isRecording = false;
                return;
            }

            // Create a new clip with the recorded length
            float[] samples = new float[recordingClip.samples * recordingClip.channels];
            recordingClip.GetData(samples, 0);

            AudioClip clippedClip = AudioClip.Create(recordingClip.name, length, recordingClip.channels, recordingClip.frequency, false);
            float[] clippedSamples = new float[length * recordingClip.channels];
            System.Array.Copy(samples, clippedSamples, clippedSamples.Length);
            clippedClip.SetData(clippedSamples, 0);

            // Save the audio clip as WAV to the agent folder
            try
            {
                string baseFolderPath = Path.Combine(Application.persistentDataPath, "Agent Presets");
                string agentFolderName = SanitizeFileName(AgentName.text);
                string agentFolderPath = Path.Combine(baseFolderPath, agentFolderName);

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

                string filePath = Path.Combine(agentFolderPath, "Agent_Voice.wav");

                // Convert and save AudioClip to WAV file using implemented method
                SaveWavFile(filePath, clippedClip);

                Debug.Log($"Recording saved to: {filePath}");
            }
            catch (System.Exception ex)
            {
                Debug.LogError($"Failed to save recorded voice: {ex.Message}");
            }

            isRecording = false;
        }
    }

    /// <summary>
    /// Save AudioClip as a proper WAV file
    /// </summary>
    /// <param name="filePath"></param>
    /// <param name="clip"></param>
    private void SaveWavFile(string filePath, AudioClip clip)
    {
        WavUtility.Save(filePath, clip);
    }

    /// <summary>
    /// Remove invalid characters from filename string
    /// </summary>
    /// <param name="filename"></param>
    /// <returns></returns>
    private string SanitizeFileName(string filename)
    {
        foreach (char c in Path.GetInvalidFileNameChars())
            filename = filename.Replace(c.ToString(), "");
        return filename;
    }

    // --- WAV utility code inserted below ---

    public static class WavUtility
    {
        private const int HEADER_SIZE = 44;

        public static void Save(string filepath, AudioClip clip)
        {
            if (clip == null)
            {
                Debug.LogError("WavUtility.Save: AudioClip is null");
                return;
            }

            Directory.CreateDirectory(Path.GetDirectoryName(filepath));

            using (var fileStream = new FileStream(filepath, FileMode.Create))
            {
                int sampleCount = clip.samples * clip.channels;
                int fileSize = sampleCount * 2 + HEADER_SIZE;

                WriteHeader(fileStream, clip, fileSize);

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

                short[] intData = new short[samples.Length];
                byte[] bytesData = new byte[samples.Length * 2];
                const float rescaleFactor = 32767f;

                for (int i = 0; i < samples.Length; i++)
                {
                    short val = (short)(Mathf.Clamp(samples[i], -1f, 1f) * rescaleFactor);
                    intData[i] = val;
                    byte[] byteArr = System.BitConverter.GetBytes(val);
                    byteArr.CopyTo(bytesData, i * 2);
                }

                fileStream.Write(bytesData, 0, bytesData.Length);
            }
        }

        private static void WriteHeader(FileStream stream, AudioClip clip, int fileSize)
        {
            int hz = clip.frequency;
            int channels = clip.channels;
            int byteRate = hz * channels * 2;

            stream.Seek(0, SeekOrigin.Begin);

            byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
            stream.Write(riff, 0, 4);

            stream.Write(System.BitConverter.GetBytes(fileSize - 8), 0, 4);

            byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
            stream.Write(wave, 0, 4);

            byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
            stream.Write(fmt, 0, 4);

            stream.Write(System.BitConverter.GetBytes(16), 0, 4); // PCM header size
            stream.Write(System.BitConverter.GetBytes((ushort)1), 0, 2); // Audio format = PCM
            stream.Write(System.BitConverter.GetBytes((ushort)channels), 0, 2);
            stream.Write(System.BitConverter.GetBytes(hz), 0, 4);
            stream.Write(System.BitConverter.GetBytes(byteRate), 0, 4);
            stream.Write(System.BitConverter.GetBytes((ushort)(channels * 2)), 0, 2); // Block align
            stream.Write(System.BitConverter.GetBytes((ushort)16), 0, 2); // Bits per sample

            byte[] dataString = System.Text.Encoding.UTF8.GetBytes("data");
            stream.Write(dataString, 0, 4);

            stream.Write(System.BitConverter.GetBytes(fileSize - HEADER_SIZE), 0, 4);
        }
    }
}