diff --git a/boards/default_src/python_pyodide/blocks/sound/play/play_frequency.js b/boards/default_src/python_pyodide/blocks/sound/play/play_frequency.js
index db7fec4d..92610f62 100644
--- a/boards/default_src/python_pyodide/blocks/sound/play/play_frequency.js
+++ b/boards/default_src/python_pyodide/blocks/sound/play/play_frequency.js
@@ -7,12 +7,12 @@ export const sound_play_frequency = {
.appendField(Blockly.Msg.MIXLY_SOUND_PLAY)
.appendField(Blockly.Msg.MIXLY_SOUND_FREQUENCY);
this.appendValueInput("FREQUENCY")
- .setCheck(null)
+ .setCheck(Number)
.setAlign(Blockly.ALIGN_RIGHT);
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_SOUND_DURATION);
this.appendValueInput("DURATION")
- .setCheck(null)
+ .setCheck(Number)
.setAlign(Blockly.ALIGN_RIGHT);
this.setPreviousStatement(true);
this.setNextStatement(true);
diff --git a/boards/default_src/python_pyodide/blocks/sound/play/play_frequency_no_duration.js b/boards/default_src/python_pyodide/blocks/sound/play/play_frequency_no_duration.js
index eb9c43fc..49ddfc42 100644
--- a/boards/default_src/python_pyodide/blocks/sound/play/play_frequency_no_duration.js
+++ b/boards/default_src/python_pyodide/blocks/sound/play/play_frequency_no_duration.js
@@ -4,7 +4,7 @@ export const sound_play_frequency_no_duration = {
init: function() {
this.setColour('#acc159');
this.appendValueInput("FREQUENCY")
- .setCheck(null)
+ .setCheck(Number)
.appendField(Blockly.Msg.MIXLY_SOUND_PLAY_FREQUENCY_NO_DURATION);
this.setPreviousStatement(true);
this.setNextStatement(true);
diff --git a/boards/default_src/python_pyodide/blocks/sound/play/play_note_list.js b/boards/default_src/python_pyodide/blocks/sound/play/play_note_list.js
index 48cf24c8..60c14062 100644
--- a/boards/default_src/python_pyodide/blocks/sound/play/play_note_list.js
+++ b/boards/default_src/python_pyodide/blocks/sound/play/play_note_list.js
@@ -4,8 +4,7 @@ export const sound_play_note_list = {
init: function() {
this.setColour('#acc159');
this.appendDummyInput()
- .appendField(Blockly.Msg.MIXLY_SOUND_PLAY_NOTE_LIST);
- this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_SOUND_PLAY_NOTE_LIST)
.appendField(new Blockly.FieldDropdown([
["DADADADUM", "DADADADUM"],
["BIRTHDAY", "BIRTHDAY"],
diff --git a/boards/default_src/python_pyodide/blocks/sound/play/sound_note.js b/boards/default_src/python_pyodide/blocks/sound/play/sound_note.js
index 82cc6a47..1a31a3b2 100644
--- a/boards/default_src/python_pyodide/blocks/sound/play/sound_note.js
+++ b/boards/default_src/python_pyodide/blocks/sound/play/sound_note.js
@@ -1,23 +1,24 @@
import * as Blockly from 'blockly/core';
export const sound_note = {
- init: function() {
+ init: function () {
this.setColour('#acc159');
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
- ["NOTE_B3", "NOTE_B3"],
- ["NOTE_C4", "NOTE_C4"],
- ["NOTE_D4", "NOTE_D4"],
- ["NOTE_E4", "NOTE_E4"],
- ["NOTE_F4", "NOTE_F4"],
- ["NOTE_G4", "NOTE_G4"],
- ["NOTE_A4", "NOTE_A4"],
- ["NOTE_B4", "NOTE_B4"],
- ["NOTE_C5", "NOTE_C5"],
- ["NOTE_D5", "NOTE_D5"],
- ["NOTE_E5", "NOTE_E5"],
- ["NOTE_F5", "NOTE_F5"],
- ["NOTE_G5", "NOTE_G5"]
+ ["NOTE_A4", "440"],
+ ["NOTE_B3", "247"],
+ ["NOTE_C4", "262"],
+ ["NOTE_D4", "294"],
+ ["NOTE_E4", "330"],
+ ["NOTE_F4", "349"],
+ ["NOTE_G4", "392"],
+ ["NOTE_A4", "440"],
+ ["NOTE_B4", "494"],
+ ["NOTE_C5", "523"],
+ ["NOTE_D5", "587"],
+ ["NOTE_E5", "659"],
+ ["NOTE_F5", "698"],
+ ["NOTE_G5", "784"]
]), "NOTE");
this.setOutput(true, null);
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
diff --git a/boards/default_src/python_pyodide/generators/sound/play/play_frequency.js b/boards/default_src/python_pyodide/generators/sound/play/play_frequency.js
index 5e7cfc0d..e2b8dda4 100644
--- a/boards/default_src/python_pyodide/generators/sound/play/play_frequency.js
+++ b/boards/default_src/python_pyodide/generators/sound/play/play_frequency.js
@@ -1,75 +1,10 @@
-function hasPlayWaitBefore(block) {
- let currentBlock = block.getPreviousBlock();
- while (currentBlock) {
- if (currentBlock.type === 'sound_play_wait') {
- return true;
- }
- currentBlock = currentBlock.getPreviousBlock();
- }
- return false;
-}
-
-export const sound_play_frequency = function(_block, generator) {
+export const sound_play_frequency = function (_block, generator) {
if (!generator.definitions_['import_sound']) {
generator.definitions_['import_sound'] = 'import sound';
}
- const frequencyInput = _block.getInputTargetBlock("FREQUENCY");
- const durationInput = _block.getInputTargetBlock("DURATION");
- let frequencyCode, durationCode;
+ const frequencyInput = generator.valueToCode(this, "FREQUENCY", generator.ORDER_ATOMIC);
+ const durationInput = generator.valueToCode(this, "DURATION", generator.ORDER_ATOMIC);
- if (frequencyInput) {
- try {
- if (frequencyInput.type === "sound_note") {
- const note = frequencyInput.getFieldValue("NOTE") || "NOTE_A4";
- const noteFrequencies = {
- "NOTE_B3": 247,
- "NOTE_C4": 262,
- "NOTE_D4": 294,
- "NOTE_E4": 330,
- "NOTE_F4": 349,
- "NOTE_G4": 392,
- "NOTE_A4": 440,
- "NOTE_B4": 494,
- "NOTE_C5": 523,
- "NOTE_D5": 587,
- "NOTE_E5": 659,
- "NOTE_F5": 698,
- "NOTE_G5": 784
- };
- frequencyCode = noteFrequencies[note] || 440;
- } else if (frequencyInput.type === "math_number") {
- const numValue = frequencyInput.getFieldValue("NUM");
- frequencyCode = numValue || "440";
- } else {
- frequencyCode = generator.valueToCode(frequencyInput, "FREQUENCY", generator.ORDER_ATOMIC);
- }
- } catch (error) {
- console.warn("生成频率代码时出错:", error);
- frequencyCode = "440";
- }
- } else {
- frequencyCode = "440";
- }
-
- if (durationInput) {
- try {
- if (durationInput.type === "math_number") {
- const numValue = durationInput.getFieldValue("NUM");
- durationCode = numValue || "1000";
- } else {
- durationCode = generator.valueToCode(durationInput, "DURATION", generator.ORDER_ATOMIC);
- }
- } catch (error) {
- console.warn("生成持续时间代码时出错:", error);
- durationCode = "1000";
- }
- } else {
- durationCode = "1000";
- }
-
- const useBlocking = hasPlayWaitBefore(_block);
- const methodName = useBlocking ? 'play_frequency_blocking' : 'play_frequency';
-
- return `sound.${methodName}(${frequencyCode}, ${durationCode})\n`;
+ return `sound.play_frequency(${frequencyInput}, ${durationInput})\n`;
};
diff --git a/boards/default_src/python_pyodide/generators/sound/play/play_frequency_no_duration.js b/boards/default_src/python_pyodide/generators/sound/play/play_frequency_no_duration.js
index 4c47f1c1..a1b6c18a 100644
--- a/boards/default_src/python_pyodide/generators/sound/play/play_frequency_no_duration.js
+++ b/boards/default_src/python_pyodide/generators/sound/play/play_frequency_no_duration.js
@@ -1,58 +1,9 @@
-function hasPlayWaitBefore(block) {
- let currentBlock = block.getPreviousBlock();
- while (currentBlock) {
- if (currentBlock.type === 'sound_play_wait') {
- return true;
- }
- currentBlock = currentBlock.getPreviousBlock();
- }
- return false;
-}
-
-export const sound_play_frequency_no_duration = function(_block, generator) {
+export const sound_play_frequency_no_duration = function (_block, generator) {
if (!generator.definitions_['import_sound']) {
generator.definitions_['import_sound'] = 'import sound';
}
- const frequencyInput = _block.getInputTargetBlock("FREQUENCY");
- let frequencyCode;
+ const frequencyInput = generator.valueToCode(this, "FREQUENCY", generator.ORDER_ATOMIC);
- if (frequencyInput) {
- try {
- if (frequencyInput.type === "sound_note") {
- const note = frequencyInput.getFieldValue("NOTE") || "NOTE_A4";
- const noteFrequencies = {
- "NOTE_B3": 247,
- "NOTE_C4": 262,
- "NOTE_D4": 294,
- "NOTE_E4": 330,
- "NOTE_F4": 349,
- "NOTE_G4": 392,
- "NOTE_A4": 440,
- "NOTE_B4": 494,
- "NOTE_C5": 523,
- "NOTE_D5": 587,
- "NOTE_E5": 659,
- "NOTE_F5": 698,
- "NOTE_G5": 784
- };
- frequencyCode = noteFrequencies[note] || 440;
- } else if (frequencyInput.type === "math_number") {
- const numValue = frequencyInput.getFieldValue("NUM");
- frequencyCode = numValue || "440";
- } else {
- frequencyCode = generator.valueToCode(frequencyInput, "FREQUENCY", generator.ORDER_ATOMIC);
- }
- } catch (error) {
- console.warn("生成频率代码时出错:", error);
- frequencyCode = "440";
- }
- } else {
- frequencyCode = "440";
- }
-
- const useBlocking = hasPlayWaitBefore(_block);
- const methodName = useBlocking ? 'play_frequency_blocking' : 'play_frequency';
-
- return `sound.${methodName}(${frequencyCode}, 0)\n`;
+ return `sound.play_frequency_no_duration(${frequencyInput})\n`;
};
diff --git a/boards/default_src/python_pyodide/generators/sound/play/play_note_list.js b/boards/default_src/python_pyodide/generators/sound/play/play_note_list.js
index 2336e091..97d56b47 100644
--- a/boards/default_src/python_pyodide/generators/sound/play/play_note_list.js
+++ b/boards/default_src/python_pyodide/generators/sound/play/play_note_list.js
@@ -1,23 +1,9 @@
-function hasPlayWaitBefore(block) {
- let currentBlock = block.getPreviousBlock();
- while (currentBlock) {
- if (currentBlock.type === 'sound_play_wait') {
- return true;
- }
- currentBlock = currentBlock.getPreviousBlock();
- }
- return false;
-}
-
export const sound_play_note_list = function(_block, _generator) {
if (!_generator.definitions_['import_sound']) {
_generator.definitions_['import_sound'] = 'import sound';
}
- const noteList = _block.getFieldValue("NOTE_LIST") || "DADADADUM";
+ const noteList = this.getFieldValue("NOTE_LIST");
- const useBlocking = hasPlayWaitBefore(_block);
- const methodName = useBlocking ? 'play_note_list_blocking' : 'play_note_list';
-
- return `sound.${methodName}("${noteList}")\n`;
+ return `sound.play_note_list("${noteList}")\n`;
};
\ No newline at end of file
diff --git a/boards/default_src/python_pyodide/generators/sound/play/sound_note.js b/boards/default_src/python_pyodide/generators/sound/play/sound_note.js
index 4241293f..8f243c8d 100644
--- a/boards/default_src/python_pyodide/generators/sound/play/sound_note.js
+++ b/boards/default_src/python_pyodide/generators/sound/play/sound_note.js
@@ -1,6 +1,7 @@
-export const sound_note = function(_block, generator) {
- const note = _block.getFieldValue("NOTE") || "NOTE_A4";
- return [`"${note}"`, generator.ORDER_ATOMIC];
+export const sound_note = function (_block, generator) {
+ // 获取频率值(字符串格式)
+ const frequency = this.getFieldValue("NOTE");
+ return [frequency, generator.ORDER_ATOMIC];
};
diff --git a/boards/default_src/python_pyodide/index.js b/boards/default_src/python_pyodide/index.js
index 02c85a14..6d0406cc 100644
--- a/boards/default_src/python_pyodide/index.js
+++ b/boards/default_src/python_pyodide/index.js
@@ -156,79 +156,58 @@ Object.assign(
import { sound_play } from './blocks/sound/play/play.js';
import { sound_play_wait } from './blocks/sound/play/play_wait.js';
import { sound_stop_all } from './blocks/sound/play/sound_stop_all.js';
-
import { sound_effect_add } from './blocks/sound/effect/add.js';
import { sound_effect_set } from './blocks/sound/effect/sound_effect_set.js';
import { sound_effect_clear } from './blocks/sound/effect/sound_effect_clear.js';
-
import { sound_volume_add } from './blocks/sound/volume/add.js';
import { sound_volume_set } from './blocks/sound/volume/set.js';
import { sound_volume_get } from './blocks/sound/volume/get.js';
-
import { sound_record } from './blocks/sound/play/record.js';
-
import { sound_play_frequency } from './blocks/sound/play/play_frequency.js';
import { sound_play_frequency_no_duration } from './blocks/sound/play/play_frequency_no_duration.js';
import { sound_play_note_list } from './blocks/sound/play/play_note_list.js';
import { sound_note } from './blocks/sound/play/sound_note.js';
-
import { sound_play as sound_play_gen } from './generators/sound/play/play.js';
import { sound_play_wait as sound_play_wait_gen } from './generators/sound/play/play_wait.js';
import { sound_stop_all as sound_stop_all_gen } from './generators/sound/play/sound_stop_all.js';
-
import { sound_effect_add as sound_effect_add_gen } from './generators/sound/effect/add.js';
import { sound_effect_set as sound_effect_set_gen } from './generators/sound/effect/sound_effect_set.js';
import { sound_effect_clear as sound_effect_clear_gen } from './generators/sound/effect/sound_effect_clear.js';
-
import { sound_volume_add as sound_volume_add_gen } from './generators/sound/volume/add.js';
import { sound_volume_set as sound_volume_set_gen } from './generators/sound/volume/set.js';
import { sound_volume_get as sound_volume_get_gen } from './generators/sound/volume/get.js';
-
import { sound_record as sound_record_gen } from './generators/sound/play/record.js';
-
import { sound_play_frequency as sound_play_frequency_gen } from './generators/sound/play/play_frequency.js';
import { sound_play_frequency_no_duration as sound_play_frequency_no_duration_gen } from './generators/sound/play/play_frequency_no_duration.js';
import { sound_play_note_list as sound_play_note_list_gen } from './generators/sound/play/play_note_list.js';
import { sound_note as sound_note_gen } from './generators/sound/play/sound_note.js';
-
-Object.assign(Blockly.Blocks, {
- sound_play,
- sound_play_wait,
- sound_stop_all,
- sound_effect_add,
- sound_effect_set,
- sound_effect_clear,
- sound_volume_add,
- sound_volume_set,
- sound_volume_get,
+const soundBlocks = {
+ sound_play, sound_play_wait, sound_stop_all,
+ sound_effect_add, sound_effect_set, sound_effect_clear,
+ sound_volume_add, sound_volume_set, sound_volume_get,
sound_record,
+ sound_play_frequency, sound_play_frequency_no_duration,
+ sound_play_note_list, sound_note
+};
- sound_play_frequency,
- sound_play_frequency_no_duration,
- sound_play_note_list,
- sound_note,
-});
-
-
-Object.assign(Blockly.Python.forBlock, {
+const soundGenerators = {
sound_play: sound_play_gen,
sound_play_wait: sound_play_wait_gen,
sound_stop_all: sound_stop_all_gen,
-
sound_effect_add: sound_effect_add_gen,
sound_effect_set: sound_effect_set_gen,
sound_effect_clear: sound_effect_clear_gen,
-
sound_volume_add: sound_volume_add_gen,
sound_volume_set: sound_volume_set_gen,
sound_volume_get: sound_volume_get_gen,
-
sound_record: sound_record_gen,
-
sound_play_frequency: sound_play_frequency_gen,
sound_play_frequency_no_duration: sound_play_frequency_no_duration_gen,
sound_play_note_list: sound_play_note_list_gen,
- sound_note: sound_note_gen,
-});
+ sound_note: sound_note_gen
+};
+
+Object.assign(Blockly.Blocks, soundBlocks);
+Object.assign(Blockly.Python.forBlock, soundGenerators);
window.sound = sound;
\ No newline at end of file
diff --git a/boards/default_src/python_pyodide/others/sound.js b/boards/default_src/python_pyodide/others/sound.js
index 436b0e1d..7e79c88d 100644
--- a/boards/default_src/python_pyodide/others/sound.js
+++ b/boards/default_src/python_pyodide/others/sound.js
@@ -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
diff --git a/boards/default_src/python_pyodide/template.xml b/boards/default_src/python_pyodide/template.xml
index 8f0660be..06e62cd6 100644
--- a/boards/default_src/python_pyodide/template.xml
+++ b/boards/default_src/python_pyodide/template.xml
@@ -3846,20 +3846,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -3916,6 +3903,20 @@
NOTE_A4
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file