audioClip 10 секунд

Общие вопросы о Unity3D

audioClip 10 секунд

Сообщение maptbih007 03 апр 2020, 10:49

Здравствуйте, опять я надоедливый maptbih007)
Сделал по предыдущей подсказке сохранение записи с микрофона в формате .wav.
Теперь возникли опять вопросы:
Почему если запись менее 10 секунд, то её заполняет пустотой до 10 секунд?
А если запись длиннее чем 10 секунд, то она сохраняется криво и размер всего несколько кБ
Код GUI:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.IO;

public class ReceiveResult : MonoBehaviour {


    AudioClip micro;
    AudioSource audioSource;
    public AudioClip audioClip;
    public string micName = "";

    public void Start()
    {
        audioSource = GetComponent<AudioSource>();
        foreach (var micName in Microphone.devices)
        {
            Debug.Log("Name: " + micName);
        }
    }

    void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 400, 200), "REC"))
        {
            micro = Microphone.Start(null, true, 10, 44100);
            audioClip = micro;
            audioSource.clip = audioClip;
            Debug.Log("START");
 
        }

        if (GUI.Button(new Rect(10, 220, 400, 200), "STOP"))
        {
            Microphone.End(micName);
            Debug.Log("Stop");
        }

        if (GUI.Button(new Rect(10, 440, 400, 200), "PLAY"))
        {
           
            audioSource.Play();
        }

        if (GUI.Button(new Rect(10, 660, 400, 200), "SAVE"))
        {
            //byte[] bytes = BitConverter.GetBytes(micro);
            //File.WriteAllBytes(Application.dataPath + "/sound.wav", bytes);

            //string deb = BitConverter.ToString(bytes);
            //Debug.Log(deb);
            SaveToWav.SavWav.Save("myfile", micro);
        }

    }

}

 


Код SaveToWav:
Синтаксис:
Используется csharp
using System;
using System.IO;
using UnityEngine;
using System.Collections.Generic;
public class SaveToWav : MonoBehaviour
{
    public static class SavWav
    {

        const int HEADER_SIZE = 44;

        public static bool Save(string filename, AudioClip clip)
        {
            if (!filename.ToLower().EndsWith(".wav"))
            {
                filename += ".wav";
            }

            var filepath = Path.Combine(Application.dataPath, filename); //for Win
            //var filepath = Path.Combine(Application.persistentDataPath, filename); //for Android "/storage/emulated/0/Android/data/<packagename>/files on most devices"

            Debug.Log(filepath);

            // Make sure directory exists if user is saving to sub dir.
            Directory.CreateDirectory(Path.GetDirectoryName(filepath));

            using (var fileStream = CreateEmpty(filepath))
            {

                ConvertAndWrite(fileStream, clip);

                WriteHeader(fileStream, clip);
            }

            return true; // TODO: return false if there's a failure saving the file
        }

        public static AudioClip TrimSilence(AudioClip clip, float min)
        {
            var samples = new float[clip.samples];

            clip.GetData(samples, 0);

            return TrimSilence(new List<float>(samples), min, clip.channels, clip.frequency);
        }

        public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz)
        {
            return TrimSilence(samples, min, channels, hz, false, false);
        }

        public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz, bool _3D, bool stream)
        {
            int i;

            for (i = 0; i < samples.Count; i++)
            {
                if (Mathf.Abs(samples[i]) > min)
                {
                    break;
                }
            }

            samples.RemoveRange(0, i);

            for (i = samples.Count - 1; i > 0; i--)
            {
                if (Mathf.Abs(samples[i]) > min)
                {
                    break;
                }
            }

            samples.RemoveRange(i, samples.Count - i);

            var clip = AudioClip.Create("TempClip", samples.Count, channels, hz, _3D, stream);

            clip.SetData(samples.ToArray(), 0);

            return clip;
        }

        static FileStream CreateEmpty(string filepath)
        {
            var fileStream = new FileStream(filepath, FileMode.Create);
            byte emptyByte = new byte();

            for (int i = 0; i < HEADER_SIZE; i++) //preparing the header
            {
                fileStream.WriteByte(emptyByte);
            }

            return fileStream;
        }

        static void ConvertAndWrite(FileStream fileStream, AudioClip clip)
        {

            var samples = new float[clip.samples];

            clip.GetData(samples, 0);

            Int16[] intData = new Int16[samples.Length];
            //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]

            Byte[] bytesData = new Byte[samples.Length * 2];
            //bytesData array is twice the size of
            //dataSource array because a float converted in Int16 is 2 bytes.

            int rescaleFactor = 32767; //to convert float to Int16

            for (int i = 0; i < samples.Length; i++)
            {
                intData[i] = (short)(samples[i] * rescaleFactor);
                Byte[] byteArr = new Byte[2];
                byteArr = BitConverter.GetBytes(intData[i]);
                byteArr.CopyTo(bytesData, i * 2);
            }

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

        static void WriteHeader(FileStream fileStream, AudioClip clip)
        {

            var hz = clip.frequency;
            var channels = clip.channels;
            var samples = clip.samples;

            fileStream.Seek(0, SeekOrigin.Begin);

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

            Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
            fileStream.Write(chunkSize, 0, 4);

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

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

            Byte[] subChunk1 = BitConverter.GetBytes(16);
            fileStream.Write(subChunk1, 0, 4);

            UInt16 two = 2;
            UInt16 one = 1;

            Byte[] audioFormat = BitConverter.GetBytes(one);
            fileStream.Write(audioFormat, 0, 2);

            Byte[] numChannels = BitConverter.GetBytes(channels);
            fileStream.Write(numChannels, 0, 2);

            Byte[] sampleRate = BitConverter.GetBytes(hz);
            fileStream.Write(sampleRate, 0, 4);

            Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2
            fileStream.Write(byteRate, 0, 4);

            UInt16 blockAlign = (ushort)(channels * 2);
            fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);

            UInt16 bps = 16;
            Byte[] bitsPerSample = BitConverter.GetBytes(bps);
            fileStream.Write(bitsPerSample, 0, 2);

            Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
            fileStream.Write(datastring, 0, 4);

            Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
            fileStream.Write(subChunk2, 0, 4);

                        //fileStream.Close();
        }
    }
}
 
maptbih007
UNец
 
Сообщения: 16
Зарегистрирован: 20 мар 2020, 13:31

Re: audioClip 10 секунд

Сообщение DbIMok 03 апр 2020, 13:54

maptbih007 писал(а):Почему если запись менее 10 секунд, то её заполняет пустотой до 10 секунд?

потому что вы выделяете буфер на 10 сек. для этого в соседнем файле TrimSilence, а в классе Microphone GetPosition
maptbih007 писал(а):А если запись длиннее чем 10 секунд, то она сохраняется криво и размер всего несколько кБ

а вы что-то сделали, чтобы больше 10 сек записывалось?
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.6k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: audioClip 10 секунд

Сообщение maptbih007 03 апр 2020, 21:20

DbIMok писал(а):
maptbih007 писал(а):Почему если запись менее 10 секунд, то её заполняет пустотой до 10 секунд?

потому что вы выделяете буфер на 10 сек. для этого в соседнем файле TrimSilence, а в классе Microphone GetPosition
maptbih007 писал(а):А если запись длиннее чем 10 секунд, то она сохраняется криво и размер всего несколько кБ

а вы что-то сделали, чтобы больше 10 сек записывалось?

Уважаемый, DbIMok!
Можно пожалуйста попросить вас визуально набросать алгоритм действий по пунктам, если можно то напишите пожалуйста в Tlg - @frizzel
Буду очень благодарен если поможете мне с развёрнутым ответом.
maptbih007
UNец
 
Сообщения: 16
Зарегистрирован: 20 мар 2020, 13:31

Re: audioClip 10 секунд

Сообщение maptbih007 04 апр 2020, 12:59

DbIMok писал(а):
maptbih007 писал(а):Почему если запись менее 10 секунд, то её заполняет пустотой до 10 секунд?

потому что вы выделяете буфер на 10 сек. для этого в соседнем файле TrimSilence, а в классе Microphone GetPosition
maptbih007 писал(а):А если запись длиннее чем 10 секунд, то она сохраняется криво и размер всего несколько кБ

а вы что-то сделали, чтобы больше 10 сек записывалось?

Что то Google не подсказывает по TrimSilence, можете подробнее написать что это?
maptbih007
UNец
 
Сообщения: 16
Зарегистрирован: 20 мар 2020, 13:31

Re: audioClip 10 секунд

Сообщение DbIMok 05 апр 2020, 15:47

TrimSilence это названия функций из файла SaveToWav, который вы приложили к первому посту. насчет алгоритма действий - вам шашечки или ехать? если второе, то проще взять готовый код который делает то что нужно на Github
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.6k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 11