chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
AudioMixer module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
from txtai.pipeline import AudioMixer
|
||||
|
||||
|
||||
class TestAudioStream(unittest.TestCase):
|
||||
"""
|
||||
AudioStream tests.
|
||||
"""
|
||||
|
||||
def testAudioStream(self):
|
||||
"""
|
||||
Test mixing audio streams
|
||||
"""
|
||||
|
||||
audio1 = np.random.rand(2, 5000), 100
|
||||
audio2 = np.random.rand(2, 5000), 100
|
||||
|
||||
mixer = AudioMixer()
|
||||
audio, rate = mixer((audio1, audio2))
|
||||
|
||||
self.assertEqual(audio.shape, (2, 5000))
|
||||
self.assertEqual(rate, 100)
|
||||
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
AudioStream module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import soundfile as sf
|
||||
|
||||
from txtai.pipeline import AudioStream
|
||||
|
||||
# pylint: disable=C0411
|
||||
from utils import Utils
|
||||
|
||||
|
||||
class TestAudioStream(unittest.TestCase):
|
||||
"""
|
||||
AudioStream tests.
|
||||
"""
|
||||
|
||||
@patch("sounddevice.play")
|
||||
def testAudioStream(self, play):
|
||||
"""
|
||||
Test playing audio
|
||||
"""
|
||||
|
||||
play.return_value = True
|
||||
|
||||
# Read audio data
|
||||
audio, rate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
stream = AudioStream()
|
||||
self.assertIsNotNone(stream([(audio, rate), AudioStream.COMPLETE]))
|
||||
|
||||
# Wait for completion
|
||||
stream.wait()
|
||||
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
Microphone module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import numpy as np
|
||||
import soundfile as sf
|
||||
|
||||
from txtai.pipeline import Microphone
|
||||
|
||||
# pylint: disable=C0411
|
||||
from utils import Utils
|
||||
|
||||
|
||||
class TestMicrophone(unittest.TestCase):
|
||||
"""
|
||||
Microphone tests.
|
||||
"""
|
||||
|
||||
# pylint: disable=C0115,C0116
|
||||
@patch("sounddevice.RawInputStream")
|
||||
def testMicrophone(self, inputstream):
|
||||
"""
|
||||
Test listening to microphone
|
||||
"""
|
||||
|
||||
class RawInputStream:
|
||||
def __init__(self, **kwargs):
|
||||
self.args = kwargs
|
||||
|
||||
# Read audio data
|
||||
self.index, self.passes = 0, 0
|
||||
audio, self.samplerate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
# Convert data to PCM
|
||||
self.audio = self.int16(audio)
|
||||
|
||||
# Start with random data to test that speech is not detected
|
||||
self.data = np.concatenate((self.audio * 50, np.zeros(shape=self.audio.shape, dtype=np.int16)))
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def read(self, size):
|
||||
# Get chunk
|
||||
chunk = self.data[self.index : self.index + size]
|
||||
self.index += size
|
||||
|
||||
# Initial pass is random data, 2nd pass is speech data
|
||||
if self.index > len(self.data):
|
||||
if not self.passes:
|
||||
self.index, self.passes = 0, self.passes + 1
|
||||
self.data = self.audio
|
||||
elif self.index >= len(self.audio) * 10:
|
||||
# Break out of loop if speech continues to not be detected
|
||||
raise IOError("Data exhausted")
|
||||
|
||||
return chunk, False
|
||||
|
||||
def int16(self, data):
|
||||
i = np.iinfo(np.int16)
|
||||
absmax = 2 ** (i.bits - 1)
|
||||
offset = i.min + absmax
|
||||
return (data * absmax + offset).clip(i.min, i.max).astype(np.int16)
|
||||
|
||||
# Mock input stream
|
||||
inputstream.side_effect = RawInputStream
|
||||
|
||||
# Create microphone pipeline and read data
|
||||
pipeline = Microphone()
|
||||
data, rate = pipeline()
|
||||
|
||||
# Validate sample rate and length of data
|
||||
self.assertEqual(len(data), 91220)
|
||||
self.assertEqual(rate, 16000)
|
||||
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
TextToAudio module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from txtai.pipeline import TextToAudio
|
||||
|
||||
|
||||
class TestTextToAudio(unittest.TestCase):
|
||||
"""
|
||||
TextToAudio tests.
|
||||
"""
|
||||
|
||||
def testTextToAudio(self):
|
||||
"""
|
||||
Test generating audio for text
|
||||
"""
|
||||
|
||||
tta = TextToAudio("hf-internal-testing/tiny-random-MusicgenForConditionalGeneration")
|
||||
|
||||
# Check that data is generated
|
||||
audio, rate = tta("This is a test")
|
||||
|
||||
self.assertGreater(len(audio), 0)
|
||||
self.assertEqual(rate, 24000)
|
||||
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
TextToSpeech module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from txtai.pipeline import TextToSpeech
|
||||
|
||||
|
||||
class TestTextToSpeech(unittest.TestCase):
|
||||
"""
|
||||
TextToSpeech tests.
|
||||
"""
|
||||
|
||||
def testESPnet(self):
|
||||
"""
|
||||
Test generating speech for text with an ESPnet model
|
||||
"""
|
||||
|
||||
tts = TextToSpeech()
|
||||
|
||||
# Check that data is generated
|
||||
speech, rate = tts("This is a test")
|
||||
|
||||
self.assertGreater(len(speech), 0)
|
||||
self.assertEqual(rate, 22050)
|
||||
|
||||
def testKokoro(self):
|
||||
"""
|
||||
Test generating speech for text with a Kokoro model
|
||||
"""
|
||||
|
||||
tts = TextToSpeech("neuml/kokoro-int8-onnx", maxtokens=2)
|
||||
|
||||
# Check that data is generated
|
||||
speech, rate = tts("This is a test")
|
||||
|
||||
self.assertGreater(len(speech), 0)
|
||||
self.assertEqual(rate, 22050)
|
||||
|
||||
@patch("onnxruntime.get_available_providers")
|
||||
@patch("torch.cuda.is_available")
|
||||
def testProviders(self, cuda, providers):
|
||||
"""
|
||||
Test that GPU provider is detected
|
||||
"""
|
||||
|
||||
# Test CUDA and onnxruntime-gpu installed
|
||||
cuda.return_value = True
|
||||
providers.return_value = ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
||||
|
||||
tts = TextToSpeech()
|
||||
self.assertEqual(tts.providers()[0][0], "CUDAExecutionProvider")
|
||||
|
||||
def testSpeechT5(self):
|
||||
"""
|
||||
Test generating speech for text with a SpeechT5 model
|
||||
"""
|
||||
|
||||
tts = TextToSpeech("neuml/txtai-speecht5-onnx")
|
||||
|
||||
# Check that data is generated
|
||||
speech, rate = tts("This is a test")
|
||||
|
||||
self.assertGreater(len(speech), 0)
|
||||
self.assertEqual(rate, 22050)
|
||||
|
||||
def testStreaming(self):
|
||||
"""
|
||||
Test streaming speech generation
|
||||
"""
|
||||
|
||||
tts = TextToSpeech()
|
||||
|
||||
# Check that data is generated
|
||||
speech, rate = list(tts("This is a test. And another".split(), stream=True))[0]
|
||||
|
||||
# Check that data is generated
|
||||
self.assertGreater(len(speech), 0)
|
||||
self.assertEqual(rate, 22050)
|
||||
@@ -0,0 +1,104 @@
|
||||
"""
|
||||
Transcription module tests
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import soundfile as sf
|
||||
|
||||
from scipy import signal
|
||||
|
||||
from txtai.pipeline import Transcription
|
||||
|
||||
# pylint: disable=C0411
|
||||
from utils import Utils
|
||||
|
||||
|
||||
class TestTranscription(unittest.TestCase):
|
||||
"""
|
||||
Transcription tests.
|
||||
"""
|
||||
|
||||
def testArray(self):
|
||||
"""
|
||||
Test audio data to text transcription
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
# Read audio data
|
||||
raw, samplerate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
self.assertEqual(transcribe((raw, samplerate)), "Make huge profits without working make up to one hundred thousand dollars a day")
|
||||
self.assertEqual(transcribe(raw, samplerate), "Make huge profits without working make up to one hundred thousand dollars a day")
|
||||
|
||||
def testChunks(self):
|
||||
"""
|
||||
Test splitting transcription into chunks
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
result = transcribe(Utils.PATH + "/Make_huge_profits.wav", join=False)[0]
|
||||
|
||||
self.assertIsInstance(result["raw"], np.ndarray)
|
||||
self.assertIsNotNone(result["rate"])
|
||||
self.assertEqual(result["text"], "Make huge profits without working make up to one hundred thousand dollars a day")
|
||||
|
||||
def testFile(self):
|
||||
"""
|
||||
Test audio file to text transcription
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
self.assertEqual(
|
||||
transcribe(Utils.PATH + "/Make_huge_profits.wav"), "Make huge profits without working make up to one hundred thousand dollars a day"
|
||||
)
|
||||
|
||||
def testGenerateArguments(self):
|
||||
"""
|
||||
Test transcription with generation keyword arguments
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
# Read audio data
|
||||
raw, samplerate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
self.assertEqual(
|
||||
transcribe(raw, samplerate, language="English", task="transcribe"),
|
||||
"Make huge profits without working make up to one hundred thousand dollars a day",
|
||||
)
|
||||
|
||||
def testResample(self):
|
||||
"""
|
||||
Test resampled audio file to text transcription
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
# Read audio data
|
||||
raw, samplerate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
# Resample for testing
|
||||
samples = round(len(raw) * float(22050) / samplerate)
|
||||
raw, samplerate = signal.resample(raw, samples), 22050
|
||||
|
||||
self.assertEqual(transcribe(raw, samplerate), "Make huge profits without working make up to one hundred thousand dollars a day")
|
||||
|
||||
def testStereo(self):
|
||||
"""
|
||||
Test audio file in stereo to text transcription
|
||||
"""
|
||||
|
||||
transcribe = Transcription()
|
||||
|
||||
# Read audio data
|
||||
raw, samplerate = sf.read(Utils.PATH + "/Make_huge_profits.wav")
|
||||
|
||||
# Convert mono to stereo
|
||||
raw = np.column_stack((raw, raw))
|
||||
|
||||
self.assertEqual(transcribe(raw, samplerate), "Make huge profits without working make up to one hundred thousand dollars a day")
|
||||
Reference in New Issue
Block a user