1
0
forked from cgvr/DeltaVR

releasing radio button starts feeding silence into Whisper stream

This commit is contained in:
2026-03-12 17:16:34 +02:00
parent f6b46784bf
commit 6e9e5cb4d4
5 changed files with 46 additions and 29 deletions

View File

@@ -179,6 +179,12 @@ public class FMODWhisperBridge : MonoBehaviour
int rate = (_nativeRate > 0) ? _nativeRate : desiredSampleRate;
if (_stream != null)
{
try { _stream.StopStream(); } catch { }
_streamStarted = false;
}
try
{
_stream = await whisper.CreateStream(rate, _nativeChannels);
@@ -247,16 +253,6 @@ public class FMODWhisperBridge : MonoBehaviour
// Pause loopback if it should only be active during recording
if (playLoopback && loopbackOnlyWhenActive && _playChannel.hasHandle())
_playChannel.setPaused(true);
// Tear down Whisper stream
if (_streamStarted)
{
try { _stream.StopStream(); } catch { /* ignore */ }
_streamStarted = false;
}
_stream = null;
Debug.Log("[FMOD→Whisper] Stream deactivated (Whisper stopped; FMOD still recording).");
}
/// <summary>
@@ -303,10 +299,6 @@ public class FMODWhisperBridge : MonoBehaviour
return;
}
// If not active, we *still* advance the ring (so we don't backlog data),
// but we *don't* push chunks to Whisper.
bool shouldFeed = isRecordingActivated && _streamStarted && _stream != null;
// Calculate byte range to lock (16-bit)
uint bytesToRead = deltaSamples * (uint)_nativeChannels * 2; // 2 bytes per sample
uint startBytes = _lastRecordPos * (uint)_nativeChannels * 2;
@@ -323,7 +315,6 @@ public class FMODWhisperBridge : MonoBehaviour
try
{
float rmsAccumulator = 0f;
int rmsSampleCount = 0;
@@ -345,13 +336,24 @@ public class FMODWhisperBridge : MonoBehaviour
currentVolumeRms = Mathf.Lerp(currentVolumeRms, rms, 1f - Mathf.Pow(1f - volumeSmoothing, Time.deltaTime * 60f));
}
// 2) Feed audio to Whisper ONLY when active
if (shouldFeed && !_skipOneFeedFrame)
// 2) Feed audio to Whisper
if (_streamStarted && _stream != null)
{
if (len1 > 0) CopyPcm16ToFloatAndFeed(p1, len1);
if (len2 > 0) CopyPcm16ToFloatAndFeed(p2, len2);
if (isRecordingActivated && !_skipOneFeedFrame)
{
// Feed real mic
if (len1 > 0) CopyPcm16ToFloatAndFeed(p1, len1);
if (len2 > 0) CopyPcm16ToFloatAndFeed(p2, len2);
}
else
{
// Feed same-size silence instead
if (len1 > 0) FeedSilentChunk(len1);
if (len2 > 0) FeedSilentChunk(len2);
}
}
// If skipping, we just discard this frame to ensure no stale data leaks.
}
finally
@@ -370,6 +372,25 @@ public class FMODWhisperBridge : MonoBehaviour
return input.Replace("[silence]", "").Replace("[ Silence ]", "").Replace("BLANK_AUDIO", "").Replace("[", "").Replace("]", "").Trim();
}
private void FeedSilentChunk(uint byteLen)
{
int samples = (int)(byteLen / 2);
EnsureTmpCapacity(samples);
// fill existing _floatTmp with zeros (efficient)
Array.Clear(_floatTmp, 0, samples);
var chunk = new AudioChunk
{
Data = _floatTmp.AsSpan(0, samples).ToArray(),
Frequency = (_nativeRate > 0) ? _nativeRate : desiredSampleRate,
Channels = _nativeChannels,
IsVoiceDetected = false
};
_stream.AddToStream(chunk);
}
private void CopyPcm16ToFloatAndFeed(IntPtr src, uint byteLen)
{
int samples = (int)(byteLen / 2); // 2 bytes per sample

View File

@@ -76,13 +76,13 @@ public class RadioTransmitter : XRGrabInteractable
private void OnRadioButtonReleased()
{
fmodWhisperBridge.DeactivateRecording();
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.RadioButton, gameObject);
}
private void OnPlayerSpeechUpdated(string text)
{
computerScreen.text = text;
//OnPlayerFinishedSpeaking?.Invoke();
}
private void OnPlayerSpeechFinished(string playerText)
@@ -93,8 +93,7 @@ public class RadioTransmitter : XRGrabInteractable
fmodWhisperBridge.OnWhisperSegmentUpdated -= OnPlayerSpeechUpdated;
fmodWhisperBridge.OnWhisperSegmentFinished -= OnPlayerSpeechFinished;
fmodWhisperBridge.DeactivateRecording();
particleEmission.enabled = false;
}
}