Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposes capture methods to AudioServer + documentation #30468

Merged
merged 2 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions doc/classes/AudioServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<return type="Array">
</return>
<description>
Returns the names of all audio input devices detected on the system.
</description>
</method>
<method name="capture_set_device">
Expand All @@ -52,6 +53,20 @@
<description>
</description>
</method>
<method name="capture_start">
<return type="int" enum="Error">
</return>
<description>
Attempts to start recording from the audio driver's capture device. On success, the return value is [constant OK].
</description>
</method>
<method name="capture_stop">
<return type="int" enum="Error">
</return>
<description>
Attempts to stop recording from the audio driver's capture device. On success, the return value is [constant OK].
</description>
</method>
<method name="generate_bus_layout" qualifiers="const">
<return type="AudioBusLayout">
</return>
Expand Down Expand Up @@ -158,11 +173,32 @@
Returns the volume of the bus at index [code]bus_idx[/code] in dB.
</description>
</method>
<method name="get_capture_buffer">
<return type="PoolIntArray">
</return>
<description>
Returns an [PoolIntArray] containing audio frames from the capture device.
</description>
</method>
<method name="get_capture_position">
<return type="int">
</return>
<description>
Returns the write position of the capture device buffer.
</description>
</method>
<method name="get_capture_size">
<return type="int">
</return>
<description>
Returns the size of the capture device buffer.
</description>
</method>
<method name="get_device_list">
<return type="Array">
</return>
<description>
Returns the names of all audio devices detected on the system.
Returns the names of all audio output devices detected on the system.
</description>
</method>
<method name="get_mix_rate" qualifiers="const">
Expand Down Expand Up @@ -388,7 +424,10 @@
Number of available audio buses.
</member>
<member name="device" type="String" setter="set_device" getter="get_device" default="&quot;Default&quot;">
Name of the current device (see [method get_device_list]).
Name of the current device for audio output (see [method get_device_list]).
</member>
<member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default="&quot;Default&quot;">
Name of the current device for audio input (see [method capture_get_device_list]).
</member>
<member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0">
Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).
Expand Down
14 changes: 7 additions & 7 deletions drivers/coreaudio/audio_driver_coreaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
if (result == noErr) {
for (int i = 0; i < inNumberFrames * ad->capture_channels; i++) {
int32_t sample = ad->input_buf[i] << 16;
ad->input_buffer_write(sample);
ad->capture_buffer_write(sample);

if (ad->capture_channels == 1) {
// In case input device is single channel convert it to Stereo
ad->input_buffer_write(sample);
// In case capture device is single channel convert it to Stereo
ad->capture_buffer_write(sample);
}
}
} else {
Expand Down Expand Up @@ -487,7 +487,7 @@ void AudioDriverCoreAudio::capture_finish() {

Error AudioDriverCoreAudio::capture_start() {

input_buffer_init(buffer_frames);
capture_buffer_init(buffer_frames);

OSStatus result = AudioOutputUnitStart(input_unit);
if (result != noErr) {
Expand Down Expand Up @@ -642,9 +642,9 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
ERR_FAIL_COND(result != noErr);

if (capture) {
// Reset audio input to keep synchronisation.
input_position = 0;
input_size = 0;
// Reset audio capture to keep synchronisation.
capture_position = 0;
capture_size = 0;
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions drivers/pulseaudio/audio_driver_pulseaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ Error AudioDriverPulseAudio::init_device() {
samples_out.resize(pa_buffer_size);

// Reset audio input to keep synchronisation.
input_position = 0;
input_size = 0;
capture_position = 0;
capture_size = 0;

return OK;
}
Expand Down Expand Up @@ -460,7 +460,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
size_t bytes = pa_stream_readable_size(ad->pa_rec_str);
if (bytes > 0) {
const void *ptr = NULL;
size_t maxbytes = ad->input_buffer.size() * sizeof(int16_t);
size_t maxbytes = ad->capture_buffer.size() * sizeof(int16_t);

bytes = MIN(bytes, maxbytes);
ret = pa_stream_peek(ad->pa_rec_str, &ptr, &bytes);
Expand All @@ -470,11 +470,11 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
int16_t *srcptr = (int16_t *)ptr;
for (size_t i = bytes >> 1; i > 0; i--) {
int32_t sample = int32_t(*srcptr++) << 16;
ad->input_buffer_write(sample);
ad->capture_buffer_write(sample);

if (ad->pa_rec_map.channels == 1) {
// In case input device is single channel convert it to Stereo
ad->input_buffer_write(sample);
// In case capture device is single channel convert it to Stereo
ad->capture_buffer_write(sample);
}
}

Expand Down Expand Up @@ -661,7 +661,7 @@ Error AudioDriverPulseAudio::capture_init_device() {
break;

default:
WARN_PRINTS("PulseAudio: Unsupported number of input channels: " + itos(pa_rec_map.channels));
WARN_PRINTS("PulseAudio: Unsupported number of capture channels: " + itos(pa_rec_map.channels));
pa_channel_map_init_stereo(&pa_rec_map);
break;
}
Expand Down Expand Up @@ -693,10 +693,10 @@ Error AudioDriverPulseAudio::capture_init_device() {
ERR_FAIL_V(ERR_CANT_OPEN);
}

input_buffer_init(input_buffer_frames);
capture_buffer_init(input_buffer_frames);

print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
print_verbose("PulseAudio: input buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");
print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " capture channels");
print_verbose("PulseAudio: capture buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");

return OK;
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/wasapi/audio_driver_wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ Error AudioDriverWASAPI::init_render_device(bool reinit) {
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
samples_in.resize(buffer_frames * channels);

input_position = 0;
input_size = 0;
capture_position = 0;
capture_size = 0;

print_verbose("WASAPI: detected " + itos(channels) + " channels");
print_verbose("WASAPI: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
Expand All @@ -363,7 +363,7 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
HRESULT hr = audio_input.audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

input_buffer_init(max_frames);
capture_buffer_init(max_frames);

return OK;
}
Expand Down Expand Up @@ -716,8 +716,8 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
}

ad->input_buffer_write(l);
ad->input_buffer_write(r);
ad->capture_buffer_write(l);
ad->capture_buffer_write(r);
}

read_frames += num_frames_available;
Expand Down
6 changes: 3 additions & 3 deletions platform/android/audio_driver_opensl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf qu

for (int i = 0; i < rec_buffer.size(); i++) {
int32_t sample = rec_buffer[i] << 16;
input_buffer_write(sample);
input_buffer_write(sample); // call twice to convert to Stereo
capture_buffer_write(sample);
capture_buffer_write(sample); // call twice to convert to Stereo
}

SLresult res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t));
Expand Down Expand Up @@ -287,7 +287,7 @@ Error AudioDriverOpenSL::capture_init_device() {

const int rec_buffer_frames = 2048;
rec_buffer.resize(rec_buffer_frames);
input_buffer_init(rec_buffer_frames);
capture_buffer_init(rec_buffer_frames);

res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t));
ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN);
Expand Down
42 changes: 21 additions & 21 deletions servers/audio/audio_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,31 @@ AudioStreamMicrophone::AudioStreamMicrophone() {

void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {

AudioDriver::get_singleton()->lock();
AudioServer::get_singleton()->lock();

Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
int mix_rate = AudioDriver::get_singleton()->get_mix_rate();
unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1);
PoolVector<int32_t> capture_buffer = AudioServer::get_singleton()->get_capture_buffer();
unsigned int capture_size = AudioServer::get_singleton()->get_capture_size();
int mix_rate = AudioServer::get_singleton()->get_mix_rate();
unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, capture_buffer.size() >> 1);
#ifdef DEBUG_ENABLED
unsigned int input_position = AudioDriver::get_singleton()->get_input_position();
unsigned int capture_position = AudioServer::get_singleton()->get_capture_position();
#endif

if (playback_delay > input_size) {
if (playback_delay > capture_size) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = AudioFrame(0.0f, 0.0f);
}
input_ofs = 0;
capture_ofs = 0;
} else {
for (int i = 0; i < p_frames; i++) {
if (input_size > input_ofs && (int)input_ofs < buf.size()) {
float l = (buf[input_ofs++] >> 16) / 32768.f;
if ((int)input_ofs >= buf.size()) {
input_ofs = 0;
if (capture_size > capture_ofs && (int)capture_ofs < capture_buffer.size()) {
float l = (capture_buffer[capture_ofs++] >> 16) / 32768.f;
if ((int)capture_ofs >= capture_buffer.size()) {
capture_ofs = 0;
}
float r = (buf[input_ofs++] >> 16) / 32768.f;
if ((int)input_ofs >= buf.size()) {
input_ofs = 0;
float r = (capture_buffer[capture_ofs++] >> 16) / 32768.f;
if ((int)capture_ofs >= capture_buffer.size()) {
capture_ofs = 0;
}

p_buffer[i] = AudioFrame(l, r);
Expand All @@ -169,12 +169,12 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
}

#ifdef DEBUG_ENABLED
if (input_ofs > input_position && (int)(input_ofs - input_position) < (p_frames * 2)) {
print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size));
if (capture_ofs > capture_position && (int)(capture_ofs - capture_position) < (p_frames * 2)) {
print_verbose(String(get_class_name()) + " buffer underrun: capture_position=" + itos(capture_position) + " capture_ofs=" + itos(capture_ofs) + " capture_size=" + itos(capture_size));
}
#endif

AudioDriver::get_singleton()->unlock();
AudioServer::get_singleton()->unlock();
}

void AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
Expand All @@ -196,17 +196,17 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
return;
}

input_ofs = 0;
capture_ofs = 0;

if (AudioDriver::get_singleton()->capture_start() == OK) {
if (AudioServer::get_singleton()->capture_start() == OK) {
active = true;
_begin_resample();
}
}

void AudioStreamPlaybackMicrophone::stop() {
if (active) {
AudioDriver::get_singleton()->capture_stop();
AudioServer::get_singleton()->capture_stop();
active = false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion servers/audio/audio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
friend class AudioStreamMicrophone;

bool active;
unsigned int input_ofs;
unsigned int capture_ofs;

Ref<AudioStreamMicrophone> microphone;

Expand Down
Loading