改声音目录

This commit is contained in:
whm1216
2025-12-02 19:11:04 +08:00
parent 3ecb7d8cfb
commit 69484c9c6b
11 changed files with 241 additions and 218 deletions

View File

@@ -632,6 +632,7 @@ const sound = {
"NOTE_G5": 784
},
// 播放指定频率的声音(带持续时间)
play_frequency: (frequency, duration = 1000) => {
try {
sound.initAudioContext();
@@ -657,31 +658,84 @@ const sound = {
gainNode.connect(sound.audioContext.destination);
oscillator.start();
if (duration > 0) {
oscillator.stop(sound.audioContext.currentTime + duration / 1000);
} else {
oscillator.stop(sound.audioContext.currentTime + 2);
}
oscillator.stop(sound.audioContext.currentTime + duration / 1000);
console.log(`播放频率: ${frequency}Hz, 持续时间: ${duration}ms, 音量: ${sound.volume}%`);
}
} catch (error) {
console.error("播放频率声音失败:", error);
}
},
play_frequency_blocking: (frequency, duration = 1000) => {
return new Promise((resolve, reject) => {
const actualDuration = duration > 0 ? duration : 2000;
// 播放指定频率的声音(持续播放,无持续时间限制)
play_frequency_continuous: (frequency) => {
try {
sound.initAudioContext();
if (sound.audioContext) {
const oscillator = sound.audioContext.createOscillator();
const gainNode = sound.audioContext.createGain();
oscillator.frequency.setValueAtTime(frequency, sound.audioContext.currentTime);
oscillator.type = 'sine';
const currentPitch = sound.effects.pitch;
if (currentPitch !== 0) {
oscillator.frequency.setValueAtTime(
frequency * Math.pow(2, currentPitch / 12),
sound.audioContext.currentTime
);
}
gainNode.gain.setValueAtTime(sound.volume / 100, sound.audioContext.currentTime);
oscillator.connect(gainNode);
gainNode.connect(sound.audioContext.destination);
oscillator.start();
oscillator.stop(sound.audioContext.currentTime + 2); // 默认播放2秒
console.log(`播放频率(持续): ${frequency}Hz, 无持续时间限制, 音量: ${sound.volume}%`);
}
} catch (error) {
console.error("播放频率声音失败:", error);
}
},
// 播放指定频率的声音(阻塞版本,使用队列,带持续时间)
play_frequency_blocking: (frequency, duration = 1000) => {
console.log(`=== 🔒 阻塞播放频率(加入队列): ${frequency}Hz, ${duration}ms ===`);
return new Promise((resolve, reject) => {
const queueItem = {
type: 'frequency',
frequency,
duration: actualDuration,
duration: duration,
resolve,
reject
};
sound.soundQueue.push(queueItem);
console.log(`✅ 频率已加入声音队列,当前队列长度: ${sound.soundQueue.length}`);
sound.processQueue();
});
},
// 播放指定频率的声音(阻塞版本,使用队列,持续播放)
play_frequency_continuous_blocking: (frequency) => {
console.log(`=== 🔒 阻塞播放频率(持续,加入队列): ${frequency}Hz ===`);
return new Promise((resolve, reject) => {
const duration = 2000; // 持续播放默认2秒
const queueItem = {
type: 'frequency',
frequency,
duration: duration,
resolve,
reject
};
sound.soundQueue.push(queueItem);
console.log(`✅ 频率(持续)已加入声音队列,当前队列长度: ${sound.soundQueue.length}`);
sound.processQueue();
});
},
@@ -1386,11 +1440,33 @@ function injectSoundToPython() {
return sound.clear_effects();
},
play_frequency: (frequency, duration) => {
console.log(`Python调用: sound.play_frequency(${frequency}, ${duration})`);
// 自动判断是否需要阻塞
if (sound.soundQueue.length > 0 || sound.isProcessingQueue) {
return sound.play_frequency_blocking(frequency, duration);
}
return sound.play_frequency(frequency, duration);
},
play_frequency_no_duration: (frequency) => {
console.log(`Python调用: sound.play_frequency_no_duration(${frequency})`);
// 自动判断是否需要阻塞
if (sound.soundQueue.length > 0 || sound.isProcessingQueue) {
return sound.play_frequency_continuous_blocking(frequency);
}
return sound.play_frequency_continuous(frequency);
},
play_frequency_blocking: (frequency, duration) => {
console.log(`Python调用: sound.play_frequency_blocking(${frequency}, ${duration})`);
return sound.play_frequency_blocking(frequency, duration);
},
play_frequency_continuous: (frequency) => {
console.log(`Python调用: sound.play_frequency_continuous(${frequency})`);
return sound.play_frequency_continuous(frequency);
},
play_frequency_continuous_blocking: (frequency) => {
console.log(`Python调用: sound.play_frequency_continuous_blocking(${frequency})`);
return sound.play_frequency_continuous_blocking(frequency);
},
play_note_list: (noteList) => {
return sound.play_note_list(noteList);
},
@@ -1463,6 +1539,100 @@ def _sync_play_blocking(name):
# 替换sound.play_blocking为同步版本
sound.play_blocking = _sync_play_blocking
# 创建同步版本的play_frequency包装函数
_original_play_frequency = sound.play_frequency
def _sync_play_frequency(frequency, duration):
"""同步版本的play_frequency会自动判断是否需要阻塞"""
promise = _original_play_frequency(frequency, duration)
# 使用Pyodide的Promise支持
import pyodide
if hasattr(pyodide, 'ffi') and hasattr(pyodide.ffi, 'run_sync'):
try:
return pyodide.ffi.run_sync(promise)
except Exception:
return None
else:
import asyncio
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def wait_promise():
try:
return await promise
except Exception:
return None
try:
return loop.run_until_complete(wait_promise())
except Exception:
return None
# 创建同步版本的play_frequency_no_duration包装函数
_original_play_frequency_no_duration = sound.play_frequency_no_duration
def _sync_play_frequency_no_duration(frequency):
"""同步版本的play_frequency_no_duration会自动判断是否需要阻塞"""
promise = _original_play_frequency_no_duration(frequency)
# 使用Pyodide的Promise支持
import pyodide
if hasattr(pyodide, 'ffi') and hasattr(pyodide.ffi, 'run_sync'):
try:
return pyodide.ffi.run_sync(promise)
except Exception:
return None
else:
import asyncio
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def wait_promise():
try:
return await promise
except Exception:
return None
try:
return loop.run_until_complete(wait_promise())
except Exception:
return None
# 替换为同步版本
sound.play_frequency = _sync_play_frequency
sound.play_frequency_no_duration = _sync_play_frequency_no_duration
# 创建同步版本的play_frequency_continuous_blocking包装函数
_original_play_frequency_continuous_blocking = sound.play_frequency_continuous_blocking
def _sync_play_frequency_continuous_blocking(frequency):
"""同步版本的play_frequency_continuous_blocking会等待频率播放完成"""
promise = _original_play_frequency_continuous_blocking(frequency)
# 使用Pyodide的Promise支持
import pyodide
if hasattr(pyodide, 'ffi') and hasattr(pyodide.ffi, 'run_sync'):
return pyodide.ffi.run_sync(promise)
else:
import asyncio
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def wait_promise():
return await promise
return loop.run_until_complete(wait_promise())
# 替换为同步版本
sound.play_frequency_continuous_blocking = _sync_play_frequency_continuous_blocking
# 创建同步版本的play_frequency_blocking包装函数
_original_play_frequency_blocking = sound.play_frequency_blocking