Skip to content

Instantly share code, notes, and snippets.

@irungentoo
Last active August 29, 2015 14:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save irungentoo/c8193a7b4f4e589e3aa9 to your computer and use it in GitHub Desktop.
Save irungentoo/c8193a7b4f4e589e3aa9 to your computer and use it in GitHub Desktop.
Openal loopback patch.
diff --git a/Alc/ALc.c b/Alc/ALc.c
index baf7f01..586cfb7 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2221,6 +2221,8 @@ static ALCvoid FreeDevice(ALCdevice *device)
al_free(device->DryBuffer);
device->DryBuffer = NULL;
+ DestroyRingBuffer(device->loopback_ring);
+
al_free(device);
}
@@ -2829,6 +2831,10 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
return 1;
+ case ALC_LOOPBACK_CAPTURE_SAMPLES:
+ values[0] = (RingBufferSize(device->loopback_ring) / 2);
+ return 1;
+
default:
alcSetError(device, ALC_INVALID_ENUM);
return 0;
@@ -3300,6 +3306,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
device->NumUpdates = 4;
device->UpdateSize = 1024;
+ device->loopback_ring = CreateRingBuffer(1, BUFFERSIZE * 4);
+
if(!PlaybackBackend.getFactory)
device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
ALCbackend_Playback);
@@ -3687,6 +3695,18 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer,
if(device) ALCdevice_DecRef(device);
}
+ALC_API void ALC_APIENTRY alcCaptureSamplesLoopback(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
+{
+ if(!(device=VerifyDevice(device)) || device->Type != Playback)
+ alcSetError(device, ALC_INVALID_DEVICE);
+ else
+ {
+ if(samples >= 0 && RingBufferSize(device->loopback_ring) >= ((ALCuint)samples * 2)) {
+ ReadRingBuffer(device->loopback_ring, buffer, samples * 2);
+ }
+ }
+ if(device) ALCdevice_DecRef(device);
+}
/************************************************
* ALC loopback functions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 33a9c41..5a39af1 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1357,6 +1357,9 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
#undef WRITE
}
+ int16_t loopback_out_array[SamplesToDo];
+ Write_ALshort(OutBuffer, loopback_out_array, SamplesToDo, 1);
+ WriteRingBuffer(device->loopback_ring, loopback_out_array, sizeof(loopback_out_array));
size -= SamplesToDo;
IncrementRef(&device->MixCount);
}
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 3a79a91..088aa32 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -620,6 +620,7 @@ typedef struct HrtfParams {
ALint DelayStep[2];
} HrtfParams;
+typedef struct RingBuffer RingBuffer;
/* Size for temporary storage of buffer data, in ALfloats. Larger values need
* more memory, while smaller values may need more iterations. The value needs
@@ -725,6 +726,8 @@ struct ALCdevice_struct
ALCdevice *volatile next;
+ RingBuffer *loopback_ring;
+
/* Memory space used by the default slot (Playback devices only) */
alignas(16) ALCbyte _slot_mem[];
};
@@ -833,7 +836,6 @@ void SetMixerFPUMode(FPUCtl *ctl);
void RestoreFPUMode(const FPUCtl *ctl);
-typedef struct RingBuffer RingBuffer;
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
void DestroyRingBuffer(RingBuffer *ring);
ALsizei RingBufferSize(RingBuffer *ring);
diff --git a/include/AL/alext.h b/include/AL/alext.h
index cb498b4..a5ea8c2 100644
--- a/include/AL/alext.h
+++ b/include/AL/alext.h
@@ -409,6 +409,9 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
#endif
+#define ALC_LOOPBACK_CAPTURE_SAMPLES 0x1004
+ALC_API void ALC_APIENTRY alcCaptureSamplesLoopback(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
+
#ifdef __cplusplus
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment