yum-archive/TaSTT-Whisper
High-performance GPGPU inference of OpenAI's Whisper automatic speech recognition (ASR) model
git clone https://git.yummers.dev/yum-archive/TaSTT-Whisper
8c4603c
master
1#include "stdafx.h" 2#include "AudioBuffer.h" 3using namespace Whisper ; 4 5void AudioBuffer ::appendMono (const float * rsi ,size_t countFloats ) 6{ 7mono .insert (mono .end (),rsi ,rsi + countFloats ); 8} 9 10void AudioBuffer ::appendStereo (const float * rsi ,size_t countFloats ) 11{ 12assert (0 == (countFloats %2 ) ); 13const size_t countSamples = countFloats /2 ; 14 15const size_t oldLength = mono .size (); 16assert (oldLength * 2 == stereo .size () ); 17mono .resize (oldLength + countSamples ); 18stereo .resize ( (oldLength + countSamples )* 2 ); 19 20const float * const rsiEnd = rsi + countSamples * 2 ; 21const float * const rsiEndAligned = rsiEnd - (countSamples * 2 ) %8 ; 22 23float * rdiStereo = & stereo [oldLength * 2 ]; 24float * rdiMono = & mono [oldLength ]; 25 26const __m128 half = _mm_set1_ps (0.5f ); 27for ( ;rsi < rsiEndAligned ;rsi += 8 ,rdiStereo += 8 ,rdiMono += 4 ) 28 { 29// Load 4 samples = 8 floats 30__m128 v0 = _mm_loadu_ps (rsi );// L0, R0, L1, R1 31__m128 v1 = _mm_loadu_ps (rsi + 4 );// L2, R2, L3, R3 32 33// Store into the stereo PCM vector 34_mm_storeu_ps (rdiStereo ,v0 ); 35_mm_storeu_ps (rdiStereo + 4 ,v1 ); 36 37// Compute and store the average of these channels 38__m128 left = _mm_shuffle_ps (v0 ,v1 ,_MM_SHUFFLE (2 ,0 ,2 ,0 ) ); 39__m128 right = _mm_shuffle_ps (v0 ,v1 ,_MM_SHUFFLE (3 ,1 ,3 ,1 ) ); 40__m128 sum = _mm_add_ps (left ,right ); 41sum = _mm_mul_ps (sum ,half ); 42_mm_storeu_ps (rdiMono ,sum ); 43 } 44 45#pragma loop (no_vector) 46for ( ;rsi < rsiEnd ;rsi += 2 ,rdiStereo += 2 ,rdiMono ++ ) 47 { 48__m128 vec = _mm_castpd_ps (_mm_load_sd ( (const double * )rsi ) ); 49_mm_store_sd ( (double * )rdiStereo ,_mm_castps_pd (vec ) ); 50 51vec = _mm_add_ss (vec ,_mm_movehdup_ps (vec ) ); 52vec = _mm_mul_ss (vec ,half ); 53_mm_store_ss (rdiMono ,vec ); 54 } 55} 56 57void AudioBuffer ::appendDownmixedStereo (const float * rsi ,size_t countFloats ) 58{ 59assert (0 == (countFloats %2 ) ); 60const size_t countSamples = countFloats /2 ; 61 62const size_t oldLength = mono .size (); 63mono .resize (oldLength + countSamples ); 64 65const float * const rsiEnd = rsi + countSamples * 2 ; 66const float * const rsiEndAligned = rsiEnd - (countSamples * 2 ) %8 ; 67 68float * rdiMono = & mono [oldLength ]; 69 70const __m128 half = _mm_set1_ps (0.5f ); 71for ( ;rsi < rsiEndAligned ;rsi += 8 ,rdiMono += 4 ) 72 { 73// Load 4 samples = 8 floats 74__m128 v0 = _mm_loadu_ps (rsi );// L0, R0, L1, R1 75__m128 v1 = _mm_loadu_ps (rsi + 4 );// L2, R2, L3, R3 76 77// Compute and store the average of these channels 78__m128 left = _mm_shuffle_ps (v0 ,v1 ,_MM_SHUFFLE (2 ,0 ,2 ,0 ) ); 79__m128 right = _mm_shuffle_ps (v0 ,v1 ,_MM_SHUFFLE (3 ,1 ,3 ,1 ) ); 80__m128 sum = _mm_add_ps (left ,right ); 81sum = _mm_mul_ps (sum ,half ); 82_mm_storeu_ps (rdiMono ,sum ); 83 } 84 85#pragma loop (no_vector) 86for ( ;rsi < rsiEnd ;rsi += 2 ,rdiMono ++ ) 87 { 88__m128 vec = _mm_castpd_ps (_mm_load_sd ( (const double * )rsi ) ); 89vec = _mm_add_ss (vec ,_mm_movehdup_ps (vec ) ); 90vec = _mm_mul_ss (vec ,half ); 91_mm_store_ss (rdiMono ,vec ); 92 } 93}