mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
minor fixes
This commit is contained in:
2
.github/workflows/python-app.yml
vendored
2
.github/workflows/python-app.yml
vendored
@@ -128,7 +128,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Executable
|
- name: Build Executable
|
||||||
run: |
|
run: |
|
||||||
uv run nuitka --mode=app --noinclude-setuptools-mode=nofollow --noinclude-IPython-mode=nofollow --assume-yes-for-downloads PyTaiko.py
|
uv run nuitka --lto=yes --mode=app --noinclude-setuptools-mode=nofollow --noinclude-IPython-mode=nofollow --assume-yes-for-downloads PyTaiko.py
|
||||||
|
|
||||||
- name: Create Release Directory
|
- name: Create Release Directory
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ right_kat = [12]
|
|||||||
|
|
||||||
[audio]
|
[audio]
|
||||||
device_type = 0
|
device_type = 0
|
||||||
buffer_size = 16
|
|
||||||
sample_rate = -1
|
sample_rate = -1
|
||||||
exclusive = false
|
exclusive = false
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ ffi.cdef("""
|
|||||||
|
|
||||||
// Device management
|
// Device management
|
||||||
void list_host_apis(void);
|
void list_host_apis(void);
|
||||||
void init_audio_device(PaHostApiIndex host_api);
|
void init_audio_device(PaHostApiIndex host_api, double sample_rate);
|
||||||
void close_audio_device(void);
|
void close_audio_device(void);
|
||||||
bool is_audio_device_ready(void);
|
bool is_audio_device_ready(void);
|
||||||
void set_master_volume(float volume);
|
void set_master_volume(float volume);
|
||||||
@@ -128,9 +128,11 @@ except OSError as e:
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
class AudioEngine:
|
class AudioEngine:
|
||||||
def __init__(self, device_type: int):
|
def __init__(self, device_type: int, sample_rate: float):
|
||||||
self.device_type = device_type
|
self.device_type = device_type
|
||||||
self.target_sample_rate = 44100
|
if sample_rate == -1:
|
||||||
|
sample_rate = 44100
|
||||||
|
self.target_sample_rate = sample_rate
|
||||||
self.sounds = {} # sound_id -> sound struct
|
self.sounds = {} # sound_id -> sound struct
|
||||||
self.music_streams = {} # music_id -> music struct
|
self.music_streams = {} # music_id -> music struct
|
||||||
self.sound_counter = 0
|
self.sound_counter = 0
|
||||||
@@ -143,7 +145,7 @@ class AudioEngine:
|
|||||||
def init_audio_device(self) -> bool:
|
def init_audio_device(self) -> bool:
|
||||||
"""Initialize the audio device"""
|
"""Initialize the audio device"""
|
||||||
try:
|
try:
|
||||||
lib.init_audio_device(self.device_type)
|
lib.init_audio_device(self.device_type, self.target_sample_rate)
|
||||||
self.audio_device_ready = lib.is_audio_device_ready()
|
self.audio_device_ready = lib.is_audio_device_ready()
|
||||||
if self.audio_device_ready:
|
if self.audio_device_ready:
|
||||||
print("Audio device initialized successfully")
|
print("Audio device initialized successfully")
|
||||||
@@ -358,4 +360,4 @@ class AudioEngine:
|
|||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
# Create the global audio instance
|
# Create the global audio instance
|
||||||
audio = AudioEngine(get_config()["audio"]["device_type"])
|
audio = AudioEngine(get_config()["audio"]["device_type"], get_config()["audio"]["sample_rate"])
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
#define FREE(ptr) do { if (ptr) { free(ptr); (ptr) = NULL; } } while(0)
|
#define FREE(ptr) do { if (ptr) { free(ptr); (ptr) = NULL; } } while(0)
|
||||||
|
|
||||||
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
|
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
|
||||||
#define AUDIO_DEVICE_SAMPLE_RATE 44100 // Device output sample rate
|
|
||||||
|
|
||||||
// Forward declarations of structures
|
// Forward declarations of structures
|
||||||
struct audio_buffer;
|
struct audio_buffer;
|
||||||
@@ -101,6 +100,7 @@ typedef struct AudioData {
|
|||||||
PaStreamParameters outputParameters; // Output stream parameters
|
PaStreamParameters outputParameters; // Output stream parameters
|
||||||
pthread_mutex_t lock; // Mutex lock for thread synchronization
|
pthread_mutex_t lock; // Mutex lock for thread synchronization
|
||||||
bool isReady; // Check if audio device is ready
|
bool isReady; // Check if audio device is ready
|
||||||
|
double sampleRate;
|
||||||
size_t pcmBufferSize; // Pre-allocated buffer size
|
size_t pcmBufferSize; // Pre-allocated buffer size
|
||||||
void *pcmBuffer; // Pre-allocated buffer to read audio data from file/memory
|
void *pcmBuffer; // Pre-allocated buffer to read audio data from file/memory
|
||||||
float masterVolume; // Master volume control
|
float masterVolume; // Master volume control
|
||||||
@@ -114,7 +114,7 @@ typedef struct AudioData {
|
|||||||
// Function declarations
|
// Function declarations
|
||||||
// Device management
|
// Device management
|
||||||
void list_host_apis(void);
|
void list_host_apis(void);
|
||||||
void init_audio_device(PaHostApiIndex host_api);
|
void init_audio_device(PaHostApiIndex host_api, double sample_rate);
|
||||||
void close_audio_device(void);
|
void close_audio_device(void);
|
||||||
bool is_audio_device_ready(void);
|
bool is_audio_device_ready(void);
|
||||||
void set_master_volume(float volume);
|
void set_master_volume(float volume);
|
||||||
@@ -322,7 +322,7 @@ PaDeviceIndex get_best_output_device_for_host_api(PaHostApiIndex hostApi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Device management implementations
|
// Device management implementations
|
||||||
void init_audio_device(PaHostApiIndex host_api)
|
void init_audio_device(PaHostApiIndex host_api, double sample_rate)
|
||||||
{
|
{
|
||||||
// Initialize PortAudio
|
// Initialize PortAudio
|
||||||
PaError err = Pa_Initialize();
|
PaError err = Pa_Initialize();
|
||||||
@@ -351,12 +351,13 @@ void init_audio_device(PaHostApiIndex host_api)
|
|||||||
AUDIO.System.outputParameters.sampleFormat = paFloat32; // Using float format like miniaudio version
|
AUDIO.System.outputParameters.sampleFormat = paFloat32; // Using float format like miniaudio version
|
||||||
AUDIO.System.outputParameters.suggestedLatency = Pa_GetDeviceInfo(AUDIO.System.outputParameters.device)->defaultLowOutputLatency;
|
AUDIO.System.outputParameters.suggestedLatency = Pa_GetDeviceInfo(AUDIO.System.outputParameters.device)->defaultLowOutputLatency;
|
||||||
AUDIO.System.outputParameters.hostApiSpecificStreamInfo = NULL;
|
AUDIO.System.outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||||
|
AUDIO.System.sampleRate = sample_rate;
|
||||||
|
|
||||||
// Open the audio stream
|
// Open the audio stream
|
||||||
err = Pa_OpenStream(&AUDIO.System.stream,
|
err = Pa_OpenStream(&AUDIO.System.stream,
|
||||||
NULL, // No input
|
NULL, // No input
|
||||||
&AUDIO.System.outputParameters, // Output parameters
|
&AUDIO.System.outputParameters, // Output parameters
|
||||||
AUDIO_DEVICE_SAMPLE_RATE, // Sample rate
|
sample_rate, // Sample rate
|
||||||
paFramesPerBufferUnspecified, // Frames per buffer (let PortAudio decide)
|
paFramesPerBufferUnspecified, // Frames per buffer (let PortAudio decide)
|
||||||
paClipOff, // No clipping
|
paClipOff, // No clipping
|
||||||
port_audio_callback, // Callback function
|
port_audio_callback, // Callback function
|
||||||
@@ -390,7 +391,7 @@ void init_audio_device(PaHostApiIndex host_api)
|
|||||||
TRACELOG(LOG_INFO, " > Device: %s", deviceInfo->name);
|
TRACELOG(LOG_INFO, " > Device: %s", deviceInfo->name);
|
||||||
TRACELOG(LOG_INFO, " > Format: %s", "Float32");
|
TRACELOG(LOG_INFO, " > Format: %s", "Float32");
|
||||||
TRACELOG(LOG_INFO, " > Channels: %d", AUDIO_DEVICE_CHANNELS);
|
TRACELOG(LOG_INFO, " > Channels: %d", AUDIO_DEVICE_CHANNELS);
|
||||||
TRACELOG(LOG_INFO, " > Sample rate: %d", AUDIO_DEVICE_SAMPLE_RATE);
|
TRACELOG(LOG_INFO, " > Sample rate: %f", AUDIO.System.sampleRate);
|
||||||
TRACELOG(LOG_INFO, " > Latency: %f ms", AUDIO.System.outputParameters.suggestedLatency * 1000.0);
|
TRACELOG(LOG_INFO, " > Latency: %f ms", AUDIO.System.outputParameters.suggestedLatency * 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,13 +658,13 @@ sound load_sound_from_wave(wave wave) {
|
|||||||
struct wave resampled_wave = { 0 };
|
struct wave resampled_wave = { 0 };
|
||||||
bool is_resampled = false;
|
bool is_resampled = false;
|
||||||
|
|
||||||
if (wave.sampleRate != AUDIO_DEVICE_SAMPLE_RATE) {
|
if (wave.sampleRate != AUDIO.System.sampleRate) {
|
||||||
TRACELOG(LOG_INFO, "AUDIO: Resampling wave from %d Hz to %d Hz", wave.sampleRate, AUDIO_DEVICE_SAMPLE_RATE);
|
TRACELOG(LOG_INFO, "AUDIO: Resampling wave from %d Hz to %f Hz", wave.sampleRate, AUDIO.System.sampleRate);
|
||||||
|
|
||||||
SRC_DATA src_data;
|
SRC_DATA src_data;
|
||||||
src_data.data_in = wave.data;
|
src_data.data_in = wave.data;
|
||||||
src_data.input_frames = wave.frameCount;
|
src_data.input_frames = wave.frameCount;
|
||||||
src_data.src_ratio = (double)AUDIO_DEVICE_SAMPLE_RATE / wave.sampleRate;
|
src_data.src_ratio = AUDIO.System.sampleRate / wave.sampleRate;
|
||||||
src_data.output_frames = (sf_count_t)(wave.frameCount * src_data.src_ratio);
|
src_data.output_frames = (sf_count_t)(wave.frameCount * src_data.src_ratio);
|
||||||
|
|
||||||
resampled_wave.data = calloc(src_data.output_frames * wave.channels, sizeof(float));
|
resampled_wave.data = calloc(src_data.output_frames * wave.channels, sizeof(float));
|
||||||
@@ -681,7 +682,7 @@ sound load_sound_from_wave(wave wave) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resampled_wave.frameCount = src_data.output_frames_gen;
|
resampled_wave.frameCount = src_data.output_frames_gen;
|
||||||
resampled_wave.sampleRate = AUDIO_DEVICE_SAMPLE_RATE;
|
resampled_wave.sampleRate = AUDIO.System.sampleRate;
|
||||||
resampled_wave.channels = wave.channels;
|
resampled_wave.channels = wave.channels;
|
||||||
resampled_wave.sampleSize = wave.sampleSize;
|
resampled_wave.sampleSize = wave.sampleSize;
|
||||||
is_resampled = true;
|
is_resampled = true;
|
||||||
@@ -790,7 +791,7 @@ audio_stream load_audio_stream(unsigned int sample_rate, unsigned int sample_siz
|
|||||||
stream.channels = channels;
|
stream.channels = channels;
|
||||||
|
|
||||||
// Pass 1 to indicate this is a streaming buffer
|
// Pass 1 to indicate this is a streaming buffer
|
||||||
stream.buffer = load_audio_buffer(AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, 1);
|
stream.buffer = load_audio_buffer(AUDIO_DEVICE_CHANNELS, AUDIO.System.sampleRate, 1);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,8 +885,8 @@ music load_music_stream(const char* filename) {
|
|||||||
}
|
}
|
||||||
ctx->snd_file = snd_file;
|
ctx->snd_file = snd_file;
|
||||||
|
|
||||||
if (sf_info.samplerate != AUDIO_DEVICE_SAMPLE_RATE) {
|
if (sf_info.samplerate != AUDIO.System.sampleRate) {
|
||||||
TRACELOG(LOG_INFO, "AUDIO: Resampling music from %d Hz to %d Hz", sf_info.samplerate, AUDIO_DEVICE_SAMPLE_RATE);
|
TRACELOG(LOG_INFO, "AUDIO: Resampling music from %d Hz to %f Hz", sf_info.samplerate, AUDIO.System.sampleRate);
|
||||||
int error;
|
int error;
|
||||||
ctx->resampler = src_new(SRC_SINC_FASTEST, sf_info.channels, &error);
|
ctx->resampler = src_new(SRC_SINC_FASTEST, sf_info.channels, &error);
|
||||||
if (ctx->resampler == NULL) {
|
if (ctx->resampler == NULL) {
|
||||||
@@ -894,7 +895,7 @@ music load_music_stream(const char* filename) {
|
|||||||
sf_close(snd_file);
|
sf_close(snd_file);
|
||||||
return music;
|
return music;
|
||||||
}
|
}
|
||||||
ctx->src_ratio = (double)AUDIO_DEVICE_SAMPLE_RATE / sf_info.samplerate;
|
ctx->src_ratio = AUDIO.System.sampleRate / sf_info.samplerate;
|
||||||
} else {
|
} else {
|
||||||
ctx->resampler = NULL;
|
ctx->resampler = NULL;
|
||||||
ctx->src_ratio = 1.0;
|
ctx->src_ratio = 1.0;
|
||||||
@@ -902,7 +903,7 @@ music load_music_stream(const char* filename) {
|
|||||||
|
|
||||||
music.ctxData = ctx;
|
music.ctxData = ctx;
|
||||||
int sample_size = 32; // We will work with floats internally
|
int sample_size = 32; // We will work with floats internally
|
||||||
music.stream = load_audio_stream(AUDIO_DEVICE_SAMPLE_RATE, sample_size, sf_info.channels);
|
music.stream = load_audio_stream(AUDIO.System.sampleRate, sample_size, sf_info.channels);
|
||||||
music.frameCount = (unsigned int)(sf_info.frames * ctx->src_ratio);
|
music.frameCount = (unsigned int)(sf_info.frames * ctx->src_ratio);
|
||||||
music_loaded = true;
|
music_loaded = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <portaudio.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -78,7 +79,7 @@ void list_host_apis(void);
|
|||||||
* Initialize the audio device and system
|
* Initialize the audio device and system
|
||||||
* Must be called before using any other audio functions
|
* Must be called before using any other audio functions
|
||||||
*/
|
*/
|
||||||
void init_audio_device(void);
|
void init_audio_device(PaHostApiIndex host_api, double sample_rate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the audio device and cleanup resources
|
* Close the audio device and cleanup resources
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class SettingsScreen:
|
|||||||
global_data.config = self.config
|
global_data.config = self.config
|
||||||
audio.close_audio_device()
|
audio.close_audio_device()
|
||||||
audio.device_type = global_data.config["audio"]["device_type"]
|
audio.device_type = global_data.config["audio"]["device_type"]
|
||||||
|
audio.target_sample_rate = global_data.config["audio"]["sample_rate"]
|
||||||
audio.init_audio_device()
|
audio.init_audio_device()
|
||||||
return "ENTRY"
|
return "ENTRY"
|
||||||
|
|
||||||
@@ -56,7 +57,6 @@ class SettingsScreen:
|
|||||||
step_sizes = {
|
step_sizes = {
|
||||||
'judge_offset': 1,
|
'judge_offset': 1,
|
||||||
'visual_offset': 1,
|
'visual_offset': 1,
|
||||||
'buffer_size': 1,
|
|
||||||
'sample_rate': 1000,
|
'sample_rate': 1000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user