Experimental microphone support.

This commit is contained in:
Saracen
2018-02-27 07:54:56 +00:00
parent 6afabc0335
commit f85062495c
23 changed files with 1058 additions and 27 deletions

View File

@ -125,6 +125,28 @@ void AudioDriverDummy::finish() {
thread = NULL;
};
bool AudioDriverDummy::capture_device_start(StringName p_name) {
return false;
}
bool AudioDriverDummy::capture_device_stop(StringName p_name) {
return false;
}
PoolStringArray AudioDriverDummy::capture_device_get_names() {
PoolStringArray names;
return names;
}
StringName AudioDriverDummy::capture_device_get_default_name() {
return "";
}
AudioDriverDummy::AudioDriverDummy() {
mutex = NULL;

View File

@ -68,6 +68,11 @@ public:
virtual void unlock();
virtual void finish();
virtual bool capture_device_start(StringName p_name);
virtual bool capture_device_stop(StringName p_name);
virtual PoolStringArray capture_device_get_names();
virtual StringName capture_device_get_default_name();
AudioDriverDummy();
~AudioDriverDummy();
};

View File

@ -99,6 +99,129 @@ void AudioStream::_bind_methods() {
////////////////////////////////
Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() {
Ref<AudioStreamPlaybackMicrophone> playback;
playback.instance();
playbacks.insert(playback.ptr());
playback->microphone = Ref<AudioStreamMicrophone>((AudioStreamMicrophone *)this);
playback->active = false;
return playback;
}
String AudioStreamMicrophone::get_stream_name() const {
//if (audio_stream.is_valid()) {
//return "Random: " + audio_stream->get_name();
//}
return "Microphone";
}
void AudioStreamMicrophone::set_microphone_name(const String &p_name) {
if (microphone_name != p_name) {
microphone_name = p_name;
for (Set<AudioStreamPlaybackMicrophone *>::Element *E = playbacks.front(); E; E = E->next()) {
if (E->get()->active) {
// Is this the right thing to do?
E->get()->stop();
E->get()->start();
}
}
}
}
StringName AudioStreamMicrophone::get_microphone_name() const {
return microphone_name;
}
float AudioStreamMicrophone::get_length() const {
return 0;
}
void AudioStreamMicrophone::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_microphone_name", "name"), &AudioStreamMicrophone::set_microphone_name);
ClassDB::bind_method(D_METHOD("get_microphone_name"), &AudioStreamMicrophone::get_microphone_name);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "microphone_name"), "set_microphone_name", "get_microphone_name");
}
AudioStreamMicrophone::AudioStreamMicrophone() {
}
void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
AudioDriver::MicrophoneDeviceOutput *microphone_device_output = reciever->owner;
const Vector<AudioFrame> &source_buffer = microphone_device_output->get_buffer();
if (microphone_device_output->get_read_index() >= 0) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = source_buffer[internal_mic_offset + microphone_device_output->get_read_index() + i];
}
}
internal_mic_offset += p_frames;
}
void AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
AudioStreamPlaybackResampled::mix(p_buffer, p_rate_scale, p_frames);
internal_mic_offset = 0; // Reset
}
float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() {
return reciever->owner->get_mix_rate();
}
void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
active = true;
// note: can this be called twice?
reciever = AudioServer::get_singleton()->create_microphone_reciever(microphone->get_microphone_name());
if (reciever == NULL) {
active = false;
}
_begin_resample();
}
void AudioStreamPlaybackMicrophone::stop() {
active = false;
if (reciever != NULL) {
AudioServer::get_singleton()->destroy_microphone_reciever(reciever);
reciever = NULL;
}
}
bool AudioStreamPlaybackMicrophone::is_playing() const {
return active;
}
int AudioStreamPlaybackMicrophone::get_loop_count() const {
return 0;
}
float AudioStreamPlaybackMicrophone::get_playback_position() const {
return 0;
}
void AudioStreamPlaybackMicrophone::seek(float p_time) {
return; // Can't seek a microphone input
}
AudioStreamPlaybackMicrophone::~AudioStreamPlaybackMicrophone() {
microphone->playbacks.erase(this);
stop();
}
AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() {
internal_mic_offset = 0;
reciever = NULL;
}
////////////////////////////////
void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
audio_stream = p_audio_stream;

View File

@ -94,6 +94,66 @@ public:
virtual float get_length() const = 0; //if supported, otherwise return 0
};
// Microphone
class AudioStreamPlaybackMicrophone;
class AudioStreamMicrophone : public AudioStream {
GDCLASS(AudioStreamMicrophone, AudioStream)
friend class AudioStreamPlaybackMicrophone;
Set<AudioStreamPlaybackMicrophone *> playbacks;
StringName microphone_name;
protected:
static void _bind_methods();
public:
virtual Ref<AudioStreamPlayback> instance_playback();
virtual String get_stream_name() const;
void set_microphone_name(const String &p_name);
StringName get_microphone_name() const;
virtual float get_length() const; //if supported, otherwise return 0
AudioStreamMicrophone();
};
class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback)
friend class AudioStreamMicrophone;
bool active;
uint64_t internal_mic_offset;
Ref<AudioStreamMicrophone> microphone;
AudioDriver::MicrophoneReciever *reciever;
protected:
virtual void _mix_internal(AudioFrame *p_buffer, int p_frames);
virtual float get_stream_sampling_rate();
public:
virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
virtual void start(float p_from_pos = 0.0);
virtual void stop();
virtual bool is_playing() const;
virtual int get_loop_count() const; //times it looped
virtual float get_playback_position() const;
virtual void seek(float p_time);
~AudioStreamPlaybackMicrophone();
AudioStreamPlaybackMicrophone();
};
//
class AudioStreamPlaybackRandomPitch;
class AudioStreamRandomPitch : public AudioStream {