Some checks failed
Bindings Tests (Go) / ubuntu-22 (push) Failing after 31s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/ppc64le, icx, icpx, ON) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm/v7, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/arm64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl-fp16 (linux/ppc64le, icx, icpx, ON) (push) Failing after 3s
CI (vad) / vad (push) Failing after 3s
CI (wasm) / emscripten (Release) (push) Failing after 4s
Bindings Tests (Ruby) / ubuntu-22 (push) Failing after 37s
CI (android) / android (push) Failing after 16s
CI (android) / android_java (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/amd64, Release) (push) Failing after 2s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Debug) (push) Failing after 3s
CI (clang) / ubuntu-22-clang (linux/ppc64le, Release) (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-low-perf (push) Failing after 3s
CI (cpu) / ggml-ci-x64-cpu-high-perf (push) Failing after 2s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/amd64, Release) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc (linux/ppc64le, Release) (push) Failing after 4s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Debug) (push) Failing after 3s
CI (gcc) / ubuntu-22-gcc-arm-v7 (linux/arm/v7, Release) (push) Failing after 3s
CI (quantize) / quantize (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (ADDRESS) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (THREAD) (push) Failing after 3s
CI (sanitize) / ubuntu-22-gcc-sanitized (UNDEFINED) (push) Failing after 2s
CI (sycl) / ubuntu-22-cmake-sycl (linux/amd64, icx, icpx, ON) (push) Failing after 3s
CI (sycl) / ubuntu-22-cmake-sycl (linux/arm64, icx, icpx, ON) (push) Failing after 3s
Examples WASM / deploy-wasm-github-pages (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (20.x) (push) Failing after 3s
Examples Tests / addon_node-ubuntu-22 (22.x) (push) Failing after 2s
CI (coreml) / coreml-base-en (push) Has been cancelled
CI (self-hosted) / gpu-vulkan (push) Has been cancelled
CI (self-hosted) / npu-amd-windows (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm2 (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Debug) (push) Has been cancelled
CI (clang) / ubuntu-22-clang-arm64 (Release) (push) Has been cancelled
CI (self-hosted) / gpu-cuda (push) Has been cancelled
CI (self-hosted) / gpu-vulkan-nvidia-cm (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-low-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf (push) Has been cancelled
CI (cpu) / ggml-ci-arm64-cpu-high-perf-sve (push) Has been cancelled
CI (freebsd) / freeBSD-latest (push) Has been cancelled
CI (self-hosted) / gpu-metal (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Debug) (push) Has been cancelled
CI (gcc) / ubuntu-22-gcc-arm64 (Release) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=iOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=macOS) (push) Has been cancelled
CI (macOS) / macOS-latest (generic/platform=tvOS) (push) Has been cancelled
CI (self-hosted) / npu-amd-linux (push) Has been cancelled
CI (windows) / windows-msys2 (Release, clang, clang-x86_64, CLANG64) (push) Has been cancelled
CI (windows) / windows-msys2 (Release, gcc, ucrt-x86_64, UCRT64) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-cuda.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-cuda]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-intel.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-intel]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-musa.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-musa]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main-vulkan]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main-vulkan.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-vulkan-arm64]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/amd64 runs_on:ubuntu-24.04 tag:main]) (push) Has been cancelled
Publish Docker image / Push Docker image to Docker Hub (map[dockerfile:.devops/main.Dockerfile platform:linux/arm64 runs_on:ubuntu-24.04-arm tag:main-arm64]) (push) Has been cancelled
Mark inactive issues stale / mark-issues (push) Failing after 1s
228 lines
6.4 KiB
C++
228 lines
6.4 KiB
C++
#include "common-sdl.h"
|
|
|
|
#include <cstdio>
|
|
|
|
audio_async::audio_async(int len_ms) {
|
|
m_len_ms = len_ms;
|
|
|
|
m_running = false;
|
|
}
|
|
|
|
audio_async::~audio_async() {
|
|
if (m_dev_id_in) {
|
|
SDL_CloseAudioDevice(m_dev_id_in);
|
|
}
|
|
}
|
|
|
|
bool audio_async::init(int capture_id, int sample_rate) {
|
|
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
|
|
|
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
|
return false;
|
|
}
|
|
|
|
SDL_SetHintWithPriority(SDL_HINT_AUDIO_RESAMPLING_MODE, "medium", SDL_HINT_OVERRIDE);
|
|
|
|
{
|
|
int nDevices = SDL_GetNumAudioDevices(SDL_TRUE);
|
|
fprintf(stderr, "%s: found %d capture devices:\n", __func__, nDevices);
|
|
for (int i = 0; i < nDevices; i++) {
|
|
fprintf(stderr, "%s: - Capture device #%d: '%s'\n", __func__, i, SDL_GetAudioDeviceName(i, SDL_TRUE));
|
|
}
|
|
}
|
|
|
|
SDL_AudioSpec capture_spec_requested;
|
|
SDL_AudioSpec capture_spec_obtained;
|
|
|
|
SDL_zero(capture_spec_requested);
|
|
SDL_zero(capture_spec_obtained);
|
|
|
|
capture_spec_requested.freq = sample_rate;
|
|
capture_spec_requested.format = AUDIO_F32;
|
|
capture_spec_requested.channels = 1;
|
|
capture_spec_requested.samples = 1024;
|
|
capture_spec_requested.callback = [](void * userdata, uint8_t * stream, int len) {
|
|
audio_async * audio = (audio_async *) userdata;
|
|
audio->callback(stream, len);
|
|
};
|
|
capture_spec_requested.userdata = this;
|
|
|
|
if (capture_id >= 0) {
|
|
fprintf(stderr, "%s: attempt to open capture device %d : '%s' ...\n", __func__, capture_id, SDL_GetAudioDeviceName(capture_id, SDL_TRUE));
|
|
m_dev_id_in = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(capture_id, SDL_TRUE), SDL_TRUE, &capture_spec_requested, &capture_spec_obtained, 0);
|
|
} else {
|
|
fprintf(stderr, "%s: attempt to open default capture device ...\n", __func__);
|
|
m_dev_id_in = SDL_OpenAudioDevice(nullptr, SDL_TRUE, &capture_spec_requested, &capture_spec_obtained, 0);
|
|
}
|
|
|
|
if (!m_dev_id_in) {
|
|
fprintf(stderr, "%s: couldn't open an audio device for capture: %s!\n", __func__, SDL_GetError());
|
|
m_dev_id_in = 0;
|
|
|
|
return false;
|
|
} else {
|
|
fprintf(stderr, "%s: obtained spec for input device (SDL Id = %d):\n", __func__, m_dev_id_in);
|
|
fprintf(stderr, "%s: - sample rate: %d\n", __func__, capture_spec_obtained.freq);
|
|
fprintf(stderr, "%s: - format: %d (required: %d)\n", __func__, capture_spec_obtained.format,
|
|
capture_spec_requested.format);
|
|
fprintf(stderr, "%s: - channels: %d (required: %d)\n", __func__, capture_spec_obtained.channels,
|
|
capture_spec_requested.channels);
|
|
fprintf(stderr, "%s: - samples per frame: %d\n", __func__, capture_spec_obtained.samples);
|
|
}
|
|
|
|
m_sample_rate = capture_spec_obtained.freq;
|
|
|
|
m_audio.resize((m_sample_rate*m_len_ms)/1000);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool audio_async::resume() {
|
|
if (!m_dev_id_in) {
|
|
fprintf(stderr, "%s: no audio device to resume!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
if (m_running) {
|
|
fprintf(stderr, "%s: already running!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
SDL_PauseAudioDevice(m_dev_id_in, 0);
|
|
|
|
m_running = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool audio_async::pause() {
|
|
if (!m_dev_id_in) {
|
|
fprintf(stderr, "%s: no audio device to pause!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
if (!m_running) {
|
|
fprintf(stderr, "%s: already paused!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
SDL_PauseAudioDevice(m_dev_id_in, 1);
|
|
|
|
m_running = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool audio_async::clear() {
|
|
if (!m_dev_id_in) {
|
|
fprintf(stderr, "%s: no audio device to clear!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
if (!m_running) {
|
|
fprintf(stderr, "%s: not running!\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
m_audio_pos = 0;
|
|
m_audio_len = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// callback to be called by SDL
|
|
void audio_async::callback(uint8_t * stream, int len) {
|
|
if (!m_running) {
|
|
return;
|
|
}
|
|
|
|
size_t n_samples = len / sizeof(float);
|
|
|
|
if (n_samples > m_audio.size()) {
|
|
n_samples = m_audio.size();
|
|
|
|
stream += (len - (n_samples * sizeof(float)));
|
|
}
|
|
|
|
//fprintf(stderr, "%s: %zu samples, pos %zu, len %zu\n", __func__, n_samples, m_audio_pos, m_audio_len);
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
if (m_audio_pos + n_samples > m_audio.size()) {
|
|
const size_t n0 = m_audio.size() - m_audio_pos;
|
|
|
|
memcpy(&m_audio[m_audio_pos], stream, n0 * sizeof(float));
|
|
memcpy(&m_audio[0], stream + n0 * sizeof(float), (n_samples - n0) * sizeof(float));
|
|
} else {
|
|
memcpy(&m_audio[m_audio_pos], stream, n_samples * sizeof(float));
|
|
}
|
|
m_audio_pos = (m_audio_pos + n_samples) % m_audio.size();
|
|
m_audio_len = std::min(m_audio_len + n_samples, m_audio.size());
|
|
}
|
|
}
|
|
|
|
void audio_async::get(int ms, std::vector<float> & result) {
|
|
if (!m_dev_id_in) {
|
|
fprintf(stderr, "%s: no audio device to get audio from!\n", __func__);
|
|
return;
|
|
}
|
|
|
|
if (!m_running) {
|
|
fprintf(stderr, "%s: not running!\n", __func__);
|
|
return;
|
|
}
|
|
|
|
result.clear();
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
if (ms <= 0) {
|
|
ms = m_len_ms;
|
|
}
|
|
|
|
size_t n_samples = (m_sample_rate * ms) / 1000;
|
|
if (n_samples > m_audio_len) {
|
|
n_samples = m_audio_len;
|
|
}
|
|
|
|
result.resize(n_samples);
|
|
|
|
int s0 = m_audio_pos - n_samples;
|
|
if (s0 < 0) {
|
|
s0 += m_audio.size();
|
|
}
|
|
|
|
if (s0 + n_samples > m_audio.size()) {
|
|
const size_t n0 = m_audio.size() - s0;
|
|
|
|
memcpy(result.data(), &m_audio[s0], n0 * sizeof(float));
|
|
memcpy(&result[n0], &m_audio[0], (n_samples - n0) * sizeof(float));
|
|
} else {
|
|
memcpy(result.data(), &m_audio[s0], n_samples * sizeof(float));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool sdl_poll_events() {
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
switch (event.type) {
|
|
case SDL_QUIT:
|
|
{
|
|
return false;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|