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

KonstantinSource codes8c4603c

master
2.9 KiB93 linesraw
1#include "stdafx.h"
2#include "AudioBuffer.h"
3using namespace Whisper;
4
5void AudioBuffer::appendMono( const float* rsi, size_t countFloats )
6{
7	mono.insert( mono.end(), rsi, rsi + countFloats );
8}
9
10void AudioBuffer::appendStereo( const float* rsi, size_t countFloats )
11{
12	assert( 0 == ( countFloats % 2 ) );
13	const size_t countSamples = countFloats / 2;
14
15	const size_t oldLength = mono.size();
16	assert( oldLength * 2 == stereo.size() );
17	mono.resize( oldLength + countSamples );
18	stereo.resize( ( oldLength + countSamples ) * 2 );
19
20	const float* const rsiEnd = rsi + countSamples * 2;
21	const float* const rsiEndAligned = rsiEnd - ( countSamples * 2 ) % 8;
22
23	float* rdiStereo = &stereo[ oldLength * 2 ];
24	float* rdiMono = &mono[ oldLength ];
25
26	const __m128 half = _mm_set1_ps( 0.5f );
27	for( ; 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 );
41		sum = _mm_mul_ps( sum, half );
42		_mm_storeu_ps( rdiMono, sum );
43	}
44
45#pragma loop (no_vector)
46	for( ; 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
51		vec = _mm_add_ss( vec, _mm_movehdup_ps( vec ) );
52		vec = _mm_mul_ss( vec, half );
53		_mm_store_ss( rdiMono, vec );
54	}
55}
56
57void AudioBuffer::appendDownmixedStereo( const float* rsi, size_t countFloats )
58{
59	assert( 0 == ( countFloats % 2 ) );
60	const size_t countSamples = countFloats / 2;
61
62	const size_t oldLength = mono.size();
63	mono.resize( oldLength + countSamples );
64
65	const float* const rsiEnd = rsi + countSamples * 2;
66	const float* const rsiEndAligned = rsiEnd - ( countSamples * 2 ) % 8;
67
68	float* rdiMono = &mono[ oldLength ];
69
70	const __m128 half = _mm_set1_ps( 0.5f );
71	for( ; 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 );
81		sum = _mm_mul_ps( sum, half );
82		_mm_storeu_ps( rdiMono, sum );
83	}
84
85#pragma loop (no_vector)
86	for( ; rsi < rsiEnd; rsi += 2, rdiMono++ )
87	{
88		__m128 vec = _mm_castpd_ps( _mm_load_sd( (const double*)rsi ) );
89		vec = _mm_add_ss( vec, _mm_movehdup_ps( vec ) );
90		vec = _mm_mul_ss( vec, half );
91		_mm_store_ss( rdiMono, vec );
92	}
93}