mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 03:30:13 +01:00
add more verbose ASIO debugging
This commit is contained in:
13
.github/workflows/python-app.yml
vendored
13
.github/workflows/python-app.yml
vendored
@@ -44,7 +44,6 @@ jobs:
|
||||
mingw-w64-x86_64-speex
|
||||
mingw-w64-x86_64-cmake
|
||||
mingw-w64-x86_64-pkg-config
|
||||
# Note: Removed mingw-w64-x86_64-portaudio since we're using our own
|
||||
|
||||
- name: Verify local PortAudio library (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
@@ -199,6 +198,12 @@ jobs:
|
||||
sudo make install
|
||||
shell: bash
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PyTaiko-${{ runner.os }}-${{ runner.arch }}
|
||||
path: release/
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
|
||||
@@ -264,12 +269,6 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PyTaiko-${{ runner.os }}-${{ runner.arch }}
|
||||
path: release/
|
||||
|
||||
- name: Upload Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||
|
||||
11
config.toml
11
config.toml
@@ -32,9 +32,18 @@ right_don = [17]
|
||||
right_kat = [12]
|
||||
|
||||
[audio]
|
||||
# device_type: 0 = default, check console output from list_host_apis() for other options
|
||||
device_type = 0
|
||||
# sample_rate: -1 = use device default (usually 44100 or 48000)
|
||||
sample_rate = -1
|
||||
buffer_size = 0
|
||||
# buffer_size: Size in samples per audio buffer
|
||||
# - 0 = let driver choose (may result in very small buffers with ASIO, typically 64)
|
||||
# - ASIO users: Use 128, 256, 512, 1024, or 2048 (must be power of 2)
|
||||
# - ASIO drivers have strict minimum buffer sizes (often 64-256 samples)
|
||||
# - If you request a buffer size below the driver's minimum, it will use the minimum instead
|
||||
# - Lower = less latency but higher CPU usage; Higher = more latency but more stable
|
||||
# - Recommended: 512 for most users, 256 for low latency, 1024+ for stability
|
||||
buffer_size = 512
|
||||
exclusive = false
|
||||
|
||||
[volume]
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
// stream to portaudio
|
||||
|
||||
#include "portaudio.h"
|
||||
#ifdef _WIN32
|
||||
#include "pa_asio.h"
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -324,6 +327,44 @@ void init_audio_device(PaHostApiIndex host_api, double sample_rate, unsigned lon
|
||||
AUDIO.System.outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
AUDIO.System.sampleRate = sample_rate;
|
||||
|
||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(AUDIO.System.outputParameters.device);
|
||||
const PaHostApiInfo *hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (hostApiInfo->type == paASIO) {
|
||||
long minSize, maxSize, preferredSize, granularity;
|
||||
PaError asioErr = PaAsio_GetAvailableBufferSizes(AUDIO.System.outputParameters.device,
|
||||
&minSize, &maxSize, &preferredSize, &granularity);
|
||||
|
||||
if (asioErr == paNoError) {
|
||||
TRACELOG(LOG_INFO, "AUDIO: ASIO buffer size constraints:");
|
||||
TRACELOG(LOG_INFO, " > Minimum: %ld samples", minSize);
|
||||
TRACELOG(LOG_INFO, " > Maximum: %ld samples", maxSize);
|
||||
TRACELOG(LOG_INFO, " > Preferred: %ld samples", preferredSize);
|
||||
if (granularity == -1) {
|
||||
TRACELOG(LOG_INFO, " > Granularity: Powers of 2 only");
|
||||
} else if (granularity == 0) {
|
||||
TRACELOG(LOG_INFO, " > Granularity: Fixed size (min=max=preferred)");
|
||||
} else {
|
||||
TRACELOG(LOG_INFO, " > Granularity: %ld samples", granularity);
|
||||
}
|
||||
|
||||
// Warn if requested buffer size is out of range
|
||||
if (buffer_size > 0 && buffer_size < minSize) {
|
||||
TRACELOG(LOG_WARNING, "AUDIO: Requested buffer size (%lu) is below ASIO minimum (%ld)", buffer_size, minSize);
|
||||
TRACELOG(LOG_WARNING, "AUDIO: Driver will use %ld samples instead", minSize);
|
||||
} else if (buffer_size > maxSize) {
|
||||
TRACELOG(LOG_WARNING, "AUDIO: Requested buffer size (%lu) exceeds ASIO maximum (%ld)", buffer_size, maxSize);
|
||||
TRACELOG(LOG_WARNING, "AUDIO: Driver will use %ld samples instead", maxSize);
|
||||
} else if (buffer_size == 0) {
|
||||
TRACELOG(LOG_INFO, "AUDIO: Buffer size not specified, driver will choose (likely %ld samples)", preferredSize);
|
||||
}
|
||||
} else {
|
||||
TRACELOG(LOG_WARNING, "AUDIO: Failed to query ASIO buffer sizes: %s", Pa_GetErrorText(asioErr));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
err = Pa_OpenStream(&AUDIO.System.stream,
|
||||
NULL, // No input
|
||||
&AUDIO.System.outputParameters, // Output parameters
|
||||
@@ -351,17 +392,24 @@ void init_audio_device(PaHostApiIndex host_api, double sample_rate, unsigned lon
|
||||
|
||||
AUDIO.System.isReady = true;
|
||||
|
||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(AUDIO.System.outputParameters.device);
|
||||
const PaHostApiInfo *hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
|
||||
|
||||
TRACELOG(LOG_INFO, "AUDIO: Device initialized successfully");
|
||||
TRACELOG(LOG_INFO, " > Backend: PortAudio | %s", hostApiInfo->name);
|
||||
TRACELOG(LOG_INFO, " > Device: %s", deviceInfo->name);
|
||||
TRACELOG(LOG_INFO, " > Format: %s", "Float32");
|
||||
const PaStreamInfo *streamInfo = Pa_GetStreamInfo(AUDIO.System.stream);
|
||||
TRACELOG(LOG_INFO, " > Channels: %d", AUDIO_DEVICE_CHANNELS);
|
||||
TRACELOG(LOG_INFO, " > Sample rate: %f", AUDIO.System.sampleRate);
|
||||
TRACELOG(LOG_INFO, " > Buffer size: %lu", buffer_size);
|
||||
TRACELOG(LOG_INFO, " > Latency: %f ms", Pa_GetStreamInfo(AUDIO.System.stream)->outputLatency * 1000.0);
|
||||
TRACELOG(LOG_INFO, " > Buffer size: %lu (requested)", buffer_size);
|
||||
TRACELOG(LOG_INFO, " > Latency: %f ms", streamInfo->outputLatency * 1000.0);
|
||||
#ifdef _WIN32
|
||||
if (hostApiInfo->type == paASIO) {
|
||||
unsigned long estimatedBufferSize = (unsigned long)(streamInfo->outputLatency * AUDIO.System.sampleRate);
|
||||
TRACELOG(LOG_INFO, " > Estimated actual buffer: ~%lu samples (based on latency)", estimatedBufferSize);
|
||||
if (buffer_size > 0 && estimatedBufferSize != buffer_size) {
|
||||
TRACELOG(LOG_INFO, " > Note: ASIO driver adjusted buffer size to meet its constraints");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void close_audio_device(void)
|
||||
|
||||
@@ -16,7 +16,7 @@ class DevScreen:
|
||||
if not self.screen_init:
|
||||
self.screen_init = True
|
||||
tex.load_screen_textures('game')
|
||||
self.obj = JudgeCounter(10)
|
||||
self.obj = JudgeCounter()
|
||||
|
||||
def on_screen_end(self, next_screen: str):
|
||||
self.screen_init = False
|
||||
@@ -24,11 +24,11 @@ class DevScreen:
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
self.obj.update()
|
||||
self.obj.update(0, 0, 0, 0)
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
|
||||
return self.on_screen_end('GAME')
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_SPACE):
|
||||
self.obj = JudgeCounter(500)
|
||||
self.obj = JudgeCounter()
|
||||
|
||||
def draw(self):
|
||||
ray.draw_rectangle(0, 0, 1280, 720, ray.GREEN)
|
||||
|
||||
Reference in New Issue
Block a user