Path: blob/master/servers/audio/audio_driver_dummy.cpp
10277 views
/**************************************************************************/1/* audio_driver_dummy.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "audio_driver_dummy.h"3132#include "core/os/os.h"3334AudioDriverDummy *AudioDriverDummy::singleton = nullptr;3536Error AudioDriverDummy::init() {37active.clear();38exit_thread.clear();39samples_in = nullptr;4041if (mix_rate == -1) {42mix_rate = _get_configured_mix_rate();43}4445channels = get_channels();46samples_in = memnew_arr(int32_t, size_t(buffer_frames) * channels);4748if (use_threads) {49thread.start(AudioDriverDummy::thread_func, this);50}5152return OK;53}5455void AudioDriverDummy::thread_func(void *p_udata) {56AudioDriverDummy *ad = static_cast<AudioDriverDummy *>(p_udata);5758uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;5960while (!ad->exit_thread.is_set()) {61if (ad->active.is_set()) {62ad->lock();63ad->start_counting_ticks();6465ad->audio_server_process(ad->buffer_frames, ad->samples_in);6667ad->stop_counting_ticks();68ad->unlock();69}7071OS::get_singleton()->delay_usec(usdelay);72}73}7475void AudioDriverDummy::start() {76active.set();77}7879int AudioDriverDummy::get_mix_rate() const {80return mix_rate;81}8283AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const {84return speaker_mode;85}8687void AudioDriverDummy::lock() {88mutex.lock();89}9091void AudioDriverDummy::unlock() {92mutex.unlock();93}9495void AudioDriverDummy::set_use_threads(bool p_use_threads) {96use_threads = p_use_threads;97}9899void AudioDriverDummy::set_speaker_mode(SpeakerMode p_mode) {100speaker_mode = p_mode;101}102103void AudioDriverDummy::set_mix_rate(int p_rate) {104mix_rate = p_rate;105}106107uint32_t AudioDriverDummy::get_channels() const {108static const int channels_for_mode[4] = { 2, 4, 8, 16 };109return channels_for_mode[speaker_mode];110}111112void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) {113ERR_FAIL_COND(!active.is_set()); // If not active, should not mix.114ERR_FAIL_COND(use_threads == true); // If using threads, this will not work well.115116uint32_t todo = p_frames;117while (todo) {118uint32_t to_mix = MIN(buffer_frames, todo);119lock();120audio_server_process(to_mix, samples_in);121unlock();122123uint32_t total_samples = to_mix * channels;124125for (uint32_t i = 0; i < total_samples; i++) {126p_buffer[i] = samples_in[i];127}128129todo -= to_mix;130p_buffer += total_samples;131}132}133134void AudioDriverDummy::finish() {135if (use_threads) {136exit_thread.set();137if (thread.is_started()) {138thread.wait_to_finish();139}140}141142if (samples_in) {143memdelete_arr(samples_in);144}145}146147AudioDriverDummy::AudioDriverDummy() {148singleton = this;149}150151152