示例#1
0
        /// <summary>
        /// If the default device is recording, ends the recording session and trims the default audio clip produced.
        /// </summary>
        public void StopRecording()
        {
            if (Microphone.IsRecording(null))
            {
                m_ForcedStopRecording = true;
                Microphone.End(null);
                float recordingLengthInSeconds = Time.time - m_RecordingStartTime;
                SmartLogger.Log(DebugFlags.AudioRecordingManager, "Unity mic recording length: " + recordingLengthInSeconds + " seconds");

                // Trim the default audio clip produced by UnityEngine.Microphone to fit the actual recording length.
                var samples = new float[Mathf.CeilToInt(m_RecordedAudio.frequency * recordingLengthInSeconds)];
                m_RecordedAudio.GetData(samples, 0);
                m_RecordedAudio = AudioClip.Create("TrimmedAudio", samples.Length,
                                                   m_RecordedAudio.channels, m_RecordedAudio.frequency, false);
                m_RecordedAudio.SetData(samples, 0);
            }
        }
        /// <summary>
        /// Computes the Levenshtein Distance between two strings.
        /// This is an altered version of a script which can be found here: http://www.dotnetperls.com/levenshtein
        /// <param name="firstString">First string to compare</param>
        /// <param name="secondString">Second string to compare</param>
        /// <param name="caseSensitive">Whether the algorithm should preserve the casing of the two strings</param>
        /// </summary>
        public static int LevenshteinDistance(string firstString, string secondString, bool caseSensitive = false)
        {
            SmartLogger.Log(DebugFlags.StringUtilities, "\"" + firstString + "\" : \"" + secondString + "\"");

            int firstStringLength  = firstString.Length;
            int secondStringLength = secondString.Length;

            // Initialize a 2D array of distances, where distances[i, j] is the Levenshtein Distance between the substring of
            // the first i characters of firstString and the substring of the first j characters of secondString.
            // Trivially then, distances[i, 0] = i and distances[0, j] = j.
            var distances = new int[firstStringLength + 1, secondStringLength + 1];

            for (int i = 0; i <= firstStringLength; ++i)
            {
                distances[i, 0] = i;
            }
            for (int j = 0; j <= secondStringLength; ++j)
            {
                distances[0, j] = j;
            }

            if (!caseSensitive)
            {
                firstString  = firstString.ToLower();
                secondString = secondString.ToLower();
            }

            for (int i = 1; i <= firstStringLength; ++i)
            {
                for (int j = 1; j <= secondStringLength; ++j)
                {
                    // Either align the two current characters and take a cost of 0 if they are the same
                    // and 1 if they are different, or skip one of the characters and take a cost of 1.
                    int cost = (secondString[j - 1] == firstString[i - 1]) ? 0 : 1;
                    distances[i, j] = Math.Min(
                        Math.Min(distances[i - 1, j] + 1, distances[i, j - 1] + 1),
                        distances[i - 1, j - 1] + cost);
                }
            }

            return(distances[firstStringLength, secondStringLength]);
        }
示例#3
0
        /// <summary>
        /// Creates and returns a specific chunk of audio from the current recording.
        /// </summary>
        /// <param name="offsetInSeconds">Number of seconds from the start of the recording at which the chunk begins</param>
        /// <param name="chunkLengthInSeconds">Maximum number of seconds the audio chunk should be</param>
        /// <returns>The audio chunk, or null if the chunk length is less than or equal to 0 or if
        /// the offset is greater than or equal to the recorded audio length</returns>
        public AudioClip GetChunkOfRecordedAudio(float offsetInSeconds, float chunkLengthInSeconds)
        {
            // Check for nonsense parameters.
            if (chunkLengthInSeconds <= 0)
            {
                SmartLogger.LogError(DebugFlags.AudioRecordingManager, "Audio chunk length cannot be less than or equal to 0.");
                return(null);
            }
            if (offsetInSeconds >= m_RecordedAudio.length)
            {
                SmartLogger.LogError(DebugFlags.AudioRecordingManager, "Offset cannot be greater than or equal to the recorded audio length.");
                return(null);
            }

            // Check for parameters that can be clamped.
            if (offsetInSeconds < 0)
            {
                SmartLogger.LogWarning(DebugFlags.AudioRecordingManager, "Chunk offset is less than 0. Clamping to 0.");
                offsetInSeconds = 0;
            }
            if (offsetInSeconds + chunkLengthInSeconds > m_RecordedAudio.length)
            {
                SmartLogger.LogWarning(DebugFlags.AudioRecordingManager,
                                       "Chunk offset + length is greater than the recorded audio length. Clamping chunk length.");
                chunkLengthInSeconds = m_RecordedAudio.length - offsetInSeconds;
            }

            // The audio chunk will have a number of samples equal to [chunk length] * [audio frequency (samples-per-second)].
            var samples = new float[Mathf.CeilToInt(m_RecordedAudio.frequency * chunkLengthInSeconds)];

            // Grab samples from the recorded audio starting from the appropriate offset.
            m_RecordedAudio.GetData(samples, Mathf.FloorToInt(m_RecordedAudio.frequency * offsetInSeconds));

            // Create a new AudioClip with these samples.
            AudioClip audioChunk = AudioClip.Create("AudioChunk", samples.Length,
                                                    m_RecordedAudio.channels, m_RecordedAudio.frequency, false);

            audioChunk.SetData(samples, 0);
            return(audioChunk);
        }
示例#4
0
        /// <summary>
        /// Writes the given text to a line in the log file if m_ShouldLogToFile is true.
        /// </summary>
        /// <param name="text">Text to write to the file</param>
        public void WriteTextToFileIfShouldLog(string text)
        {
            if (m_ShouldLogToFile)
            {
                lock (m_FileLockHandle)
                {
                    SmartLogger.Log(DebugFlags.LogFileManager, "log to file");
                    if (!File.Exists(m_LogFilePath))
                    {
                        FileStream file = File.Create(m_LogFilePath);
                        file.Close();
                    }

                    using (var fileStream = new FileStream(m_LogFilePath, FileMode.Append, FileAccess.Write))
                    {
                        using (var streamWriter = new StreamWriter(fileStream))
                        {
                            streamWriter.WriteLine(text);
                        }
                        fileStream.Close();
                    }
                }
            }
        }
        /// <summary>
        /// Takes an input string and removes from it any special formatting the caller specifies.
        /// </summary>
        /// <param name="input">String to modify</param>
        /// <param name="charsToRemove">Set of individual characters to remove</param>
        /// <param name="leadingCharsForWordsToRemove">Set of leading characters for words to remove</param>
        /// <param name="surroundingCharsForTextToRemove">Dictionary of surrounding characters for text to remove,
        /// where the leading character is the key and the ending character is the value</param>
        /// <param name="removeAllNonAlphanumericOrWhitespaceChars">Whether all characters that are not alphanumeric
        /// and not whitespace should be removed</param>
        /// <param name="removeExtraWhitespace">Whether whitespace should be trimmed to a single character
        /// of whitespace and surrounding whitespace should be removed</param>
        /// <returns>The input string stripped of any specified special formatting</returns>
        public static string TrimSpecialFormatting(string input, HashSet <char> charsToRemove,
                                                   HashSet <char> leadingCharsForWordsToRemove, Dictionary <char, char> surroundingCharsForTextToRemove,
                                                   bool removeAllNonAlphanumericOrWhitespaceChars = true, bool removeExtraWhitespace = true)
        {
            string output = "";

            if (input.Length > 0)
            {
                int startIndex = 0;
                int endIndex   = input.Length - 1;
                if (removeExtraWhitespace)
                {
                    // Skip whitespace at the beginning and end.
                    while (startIndex < input.Length && char.IsWhiteSpace(input[startIndex]))
                    {
                        startIndex++;
                    }
                    while (endIndex >= 0 && char.IsWhiteSpace(input[endIndex]))
                    {
                        endIndex--;
                    }
                }

                bool       currentlyIgnoringWhitespace = false;
                bool       currentlyInWordToRemove     = false;
                const char wordSeparatorChar           = ' ';
                char       lastAddedChar                 = wordSeparatorChar;
                bool       currentlyInTextToRemove       = false;
                char       endCharForCurrentTextToRemove = '\0';

                for (int i = startIndex; i <= endIndex; ++i)
                {
                    // Ignore all characters as long as we are still within text to remove.
                    if (currentlyInTextToRemove)
                    {
                        if (input[i] == endCharForCurrentTextToRemove)
                        {
                            currentlyInTextToRemove = false;
                        }
                    }
                    // Otherwise we might still add this character.
                    else
                    {
                        // If we were within a word to remove and the current character is a word separator character,
                        // then we are no longer within a word to remove.
                        if (currentlyInWordToRemove && input[i] == wordSeparatorChar)
                        {
                            currentlyInWordToRemove = false;
                        }

                        // If we are not within a word to remove and either we are not ignoring whitespace
                        // or this character is not whitespace, we might still add this character.
                        if (!currentlyInWordToRemove && (!currentlyIgnoringWhitespace || !char.IsWhiteSpace(input[i])))
                        {
                            // If this character is the leading character for text to remove, then we are now within text to remove.
                            if (surroundingCharsForTextToRemove.ContainsKey(input[i]))
                            {
                                currentlyInTextToRemove       = true;
                                endCharForCurrentTextToRemove = surroundingCharsForTextToRemove[input[i]];
                            }
                            // If this character is both the first character in a word and the leading character
                            // for a word to remove, then we are now within a word to remove.
                            else if (leadingCharsForWordsToRemove.Contains(input[i]) && (i == 0 || lastAddedChar == wordSeparatorChar))
                            {
                                currentlyInWordToRemove = true;
                            }
                            // If this character isn't one of the given characters to remove, we might still add this character.
                            else if (!charsToRemove.Contains(input[i]) &&
                                     (!removeAllNonAlphanumericOrWhitespaceChars || char.IsLetterOrDigit(input[i]) || char.IsWhiteSpace(input[i])))
                            {
                                // If we are not ignoring whitespace or this character is not whitespace, add this character.
                                if (!currentlyIgnoringWhitespace || !char.IsWhiteSpace(input[i]))
                                {
                                    output       += input[i];
                                    lastAddedChar = input[i];
                                }

                                // Determine if we should start ignoring whitespace or stop ignoring whitespace.
                                if (!currentlyIgnoringWhitespace && char.IsWhiteSpace(input[i]) && removeExtraWhitespace)
                                {
                                    currentlyIgnoringWhitespace = true;
                                }
                                else if (currentlyIgnoringWhitespace && !char.IsWhiteSpace(input[i]))
                                {
                                    currentlyIgnoringWhitespace = false;
                                }
                            }
                        }
                    }
                }
            }

            SmartLogger.Log(DebugFlags.StringUtilities, "Original String: " + input);
            SmartLogger.Log(DebugFlags.StringUtilities, "Trimmed String: " + output);
            return(output);
        }