Skip to content

Commit 88ce191

Browse files
author
Devin Roth
committed
Clear ring buffer when no audio is being output.
1 parent a257caa commit 88ce191

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1310"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "2D7477A81578168D00412279"
18+
BuildableName = "BlackHole.driver"
19+
BlueprintName = "BlackHole"
20+
ReferencedContainer = "container:BlackHole.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
</Testables>
32+
</TestAction>
33+
<LaunchAction
34+
buildConfiguration = "Debug"
35+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
launchStyle = "0"
38+
useCustomWorkingDirectory = "NO"
39+
ignoresPersistentStateOnLaunch = "NO"
40+
debugDocumentVersioning = "YES"
41+
debugServiceExtension = "internal"
42+
allowLocationSimulation = "YES">
43+
</LaunchAction>
44+
<ProfileAction
45+
buildConfiguration = "Release"
46+
shouldUseLaunchSchemeArgsEnv = "YES"
47+
savedToolIdentifier = ""
48+
useCustomWorkingDirectory = "NO"
49+
debugDocumentVersioning = "YES">
50+
<MacroExpansion>
51+
<BuildableReference
52+
BuildableIdentifier = "primary"
53+
BlueprintIdentifier = "2D7477A81578168D00412279"
54+
BuildableName = "BlackHole.driver"
55+
BlueprintName = "BlackHole"
56+
ReferencedContainer = "container:BlackHole.xcodeproj">
57+
</BuildableReference>
58+
</MacroExpansion>
59+
</ProfileAction>
60+
<AnalyzeAction
61+
buildConfiguration = "Debug">
62+
</AnalyzeAction>
63+
<ArchiveAction
64+
buildConfiguration = "Release"
65+
revealArchiveInOrganizer = "YES">
66+
</ArchiveAction>
67+
</Scheme>

BlackHole/BlackHole.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -3779,13 +3779,25 @@ static OSStatus BlackHole_DoIOOperation(AudioServerPlugInDriverRef inDriver, Aud
37793779
secondPartFrameSize = inIOBufferFrameSize - firstPartFrameSize;
37803780
}
37813781

3782+
// Keep track of last outputSampleTime and the cleared buffer status.
3783+
static Float64 lastOutputSampleTime = 0;
3784+
static Boolean isBufferClear = true;
3785+
37823786
// From BlackHole to Application
37833787
if(inOperationID == kAudioServerPlugInIOOperationReadInput)
37843788
{
3785-
// If mute is one let's just fill the buffer with zeros
3786-
if (gMute_Master_Value || gMute_Master_Value)
3789+
// If mute is one let's just fill the buffer with zeros or if there's no apps outputing audio
3790+
if (gMute_Master_Value || lastOutputSampleTime - inIOBufferFrameSize < inIOCycleInfo->mInputTime.mSampleTime)
37873791
{
3788-
memset(ioMainBuffer, 0, inIOBufferFrameSize * kNumber_Of_Channels * sizeof(Float32));
3792+
// Clear the ioMainBuffer
3793+
vDSP_vclr(ioMainBuffer, 1, inIOBufferFrameSize * kNumber_Of_Channels);
3794+
3795+
// Clear the ring buffer.
3796+
if (!isBufferClear)
3797+
{
3798+
vDSP_vclr(gRingBuffer, 1, kRing_Buffer_Frame_Size * kNumber_Of_Channels);
3799+
isBufferClear = true;
3800+
}
37893801
}
37903802
else
37913803
{
@@ -3803,6 +3815,9 @@ static OSStatus BlackHole_DoIOOperation(AudioServerPlugInDriverRef inDriver, Aud
38033815
// From Application to BlackHole
38043816
if(inOperationID == kAudioServerPlugInIOOperationWriteMix)
38053817
{
3818+
// Save the last output time.
3819+
lastOutputSampleTime= inIOCycleInfo->mOutputTime.mSampleTime;
3820+
isBufferClear = false;
38063821

38073822
memcpy(((void*)gRingBuffer) + ringBufferFrameLocationStart * kNumber_Of_Channels * sizeof(Float32), ioMainBuffer, firstPartFrameSize * kNumber_Of_Channels * sizeof(Float32));
38083823
memcpy(gRingBuffer, ioMainBuffer + firstPartFrameSize * kNumber_Of_Channels * sizeof(Float32), secondPartFrameSize * kNumber_Of_Channels * sizeof(Float32));

0 commit comments

Comments
 (0)