sa2kit 1.6.13 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PMXParser-L6IWHL4I.mjs +4 -0
- package/dist/PMXParser-L6IWHL4I.mjs.map +1 -0
- package/dist/PMXParser-YBS3B6HM.js +13 -0
- package/dist/PMXParser-YBS3B6HM.js.map +1 -0
- package/dist/audioDetection/index.js.map +1 -1
- package/dist/audioDetection/index.mjs.map +1 -1
- package/dist/auth/index.js +3 -3
- package/dist/auth/index.mjs +1 -1
- package/dist/{chunk-FAHLZIYQ.js → chunk-5D7ZFZIM.js} +2 -2
- package/dist/{chunk-FAHLZIYQ.js.map → chunk-5D7ZFZIM.js.map} +1 -1
- package/dist/{chunk-G4AMEDO5.js → chunk-66EHKQVS.js} +2 -2
- package/dist/{chunk-G4AMEDO5.js.map → chunk-66EHKQVS.js.map} +1 -1
- package/dist/{chunk-CDK3DHKM.mjs → chunk-GGGTJETD.mjs} +3 -3
- package/dist/{chunk-CDK3DHKM.mjs.map → chunk-GGGTJETD.mjs.map} +1 -1
- package/dist/chunk-JZXJQMVE.js +363 -0
- package/dist/chunk-JZXJQMVE.js.map +1 -0
- package/dist/{chunk-2ODO4HEI.js → chunk-LFM5QSFW.js} +2 -2
- package/dist/{chunk-2ODO4HEI.js.map → chunk-LFM5QSFW.js.map} +1 -1
- package/dist/{chunk-ZYXF3L6T.mjs → chunk-MRGFYQTC.mjs} +2 -2
- package/dist/{chunk-ZYXF3L6T.mjs.map → chunk-MRGFYQTC.mjs.map} +1 -1
- package/dist/{chunk-ZCLAF3XN.mjs → chunk-TGL6BATG.mjs} +2 -2
- package/dist/{chunk-ZCLAF3XN.mjs.map → chunk-TGL6BATG.mjs.map} +1 -1
- package/dist/{chunk-L5PW2YTI.js → chunk-UUM5BIOU.js} +7 -7
- package/dist/{chunk-L5PW2YTI.js.map → chunk-UUM5BIOU.js.map} +1 -1
- package/dist/chunk-VRTRSEEH.mjs +361 -0
- package/dist/chunk-VRTRSEEH.mjs.map +1 -0
- package/dist/{chunk-6BZ3QFA5.mjs → chunk-VZFHU553.mjs} +2 -2
- package/dist/{chunk-6BZ3QFA5.mjs.map → chunk-VZFHU553.mjs.map} +1 -1
- package/dist/imageCrop/index.js.map +1 -1
- package/dist/imageCrop/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/mmd/admin/index.d.mts +1 -1
- package/dist/mmd/admin/index.d.ts +1 -1
- package/dist/mmd/index.d.mts +753 -3
- package/dist/mmd/index.d.ts +753 -3
- package/dist/mmd/index.js +7542 -5841
- package/dist/mmd/index.js.map +1 -1
- package/dist/mmd/index.mjs +7453 -5776
- package/dist/mmd/index.mjs.map +1 -1
- package/dist/mmd/server/index.d.mts +1 -1
- package/dist/mmd/server/index.d.ts +1 -1
- package/dist/music/index.js +16 -16
- package/dist/music/index.mjs +2 -2
- package/dist/music/server/index.js +8 -8
- package/dist/music/server/index.mjs +1 -1
- package/dist/testYourself/admin/index.js +3 -3
- package/dist/testYourself/admin/index.mjs +1 -1
- package/dist/testYourself/index.js +7 -7
- package/dist/testYourself/index.js.map +1 -1
- package/dist/testYourself/index.mjs +2 -2
- package/dist/testYourself/index.mjs.map +1 -1
- package/dist/{types-BB-7_WtE.d.ts → types-HorDyIRv.d.mts} +50 -0
- package/dist/{types-BB-7_WtE.d.mts → types-HorDyIRv.d.ts} +50 -0
- package/package.json +19 -17
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"PMXParser-L6IWHL4I.mjs"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkJZXJQMVE_js = require('./chunk-JZXJQMVE.js');
|
|
4
|
+
require('./chunk-DGUM43GV.js');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "PMXParser", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkJZXJQMVE_js.PMXParser; }
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=PMXParser-YBS3B6HM.js.map
|
|
13
|
+
//# sourceMappingURL=PMXParser-YBS3B6HM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"PMXParser-YBS3B6HM.js"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/audioDetection/core/AudioInputService.ts","../../src/audioDetection/core/PitchDetector.ts","../../src/audioDetection/core/ChordRecognizer.ts","../../src/audioDetection/core/AudioDetector.ts","../../src/audioDetection/core/AudioDetectorDebugger.ts","../../src/audioDetection/hooks/useAudioDetection.ts","../../src/audioDetection/components/AudioDetectionDisplay.tsx","../../src/audioDetection/components/PianoKeyboard.tsx"],"names":["useState","useRef","useEffect","useCallback","error","React","useMemo","blackKeys"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 音频输入服务\n * Audio Input Service\n * \n * 负责管理麦克风输入和音频流处理\n * Manages microphone input and audio stream processing\n */\n\nimport type { AudioInputConfig, AudioInputState } from '../types';\n\nexport class AudioInputService {\n private audioContext: AudioContext | null = null;\n private mediaStream: MediaStream | null = null;\n private sourceNode: MediaStreamAudioSourceNode | null = null;\n private analyserNode: AnalyserNode | null = null;\n private state: AudioInputState = 'idle';\n private config: Required<AudioInputConfig>;\n\n constructor(config: AudioInputConfig = {}) {\n this.config = {\n sampleRate: config.sampleRate ?? 44100,\n fftSize: config.fftSize ?? 4096,\n minVolume: config.minVolume ?? 0.001, // 降低默认阈值,使其更敏感\n minConfidence: config.minConfidence ?? 0.5, // 降低默认置信度,更容易检测\n smoothing: config.smoothing ?? 0.8,\n frequencyRange: config.frequencyRange ?? { min: 27.5, max: 4186 }, // A0 到 C8\n };\n }\n\n /**\n * 初始化音频输入\n * Initialize audio input\n */\n async initialize(): Promise<void> {\n if (this.state === 'active') {\n console.warn('AudioInputService 已经处于活动状态');\n return;\n }\n\n try {\n this.setState('initializing');\n\n // 请求麦克风权限\n this.mediaStream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n sampleRate: this.config.sampleRate,\n },\n });\n\n // 创建音频上下文\n this.audioContext = new AudioContext({\n sampleRate: this.config.sampleRate,\n });\n\n // 创建音频源节点\n this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);\n\n // 创建分析器节点\n this.analyserNode = this.audioContext.createAnalyser();\n this.analyserNode.fftSize = this.config.fftSize;\n this.analyserNode.smoothingTimeConstant = this.config.smoothing;\n\n // 连接节点\n this.sourceNode.connect(this.analyserNode);\n\n this.setState('active');\n console.log('AudioInputService 初始化成功');\n } catch (error) {\n this.setState('error');\n console.error('AudioInputService 初始化失败:', error);\n throw new Error(`麦克风初始化失败: ${error instanceof Error ? error.message : '未知错误'}`);\n }\n }\n\n /**\n * 获取时域数据\n * Get time domain data\n */\n getTimeDomainData(): Float32Array {\n if (!this.analyserNode) {\n throw new Error('AnalyserNode 未初始化');\n }\n\n const bufferLength = this.analyserNode.fftSize;\n const dataArray = new Float32Array(bufferLength);\n this.analyserNode.getFloatTimeDomainData(dataArray);\n return dataArray;\n }\n\n /**\n * 获取频域数据\n * Get frequency domain data\n */\n getFrequencyData(): Float32Array {\n if (!this.analyserNode) {\n throw new Error('AnalyserNode 未初始化');\n }\n\n const bufferLength = this.analyserNode.frequencyBinCount;\n const dataArray = new Float32Array(bufferLength);\n this.analyserNode.getFloatFrequencyData(dataArray);\n return dataArray;\n }\n\n /**\n * 获取当前音量\n * Get current volume\n */\n getCurrentVolume(): number {\n const timeDomainData = this.getTimeDomainData();\n let sum = 0;\n for (let i = 0; i < timeDomainData.length; i++) {\n const val = timeDomainData[i];\n if (val !== undefined) {\n sum += val * val;\n }\n }\n return Math.sqrt(sum / timeDomainData.length);\n }\n\n /**\n * 停止音频输入\n * Stop audio input\n */\n stop(): void {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach(track => track.stop());\n this.mediaStream = null;\n }\n\n if (this.sourceNode) {\n this.sourceNode.disconnect();\n this.sourceNode = null;\n }\n\n if (this.analyserNode) {\n this.analyserNode.disconnect();\n this.analyserNode = null;\n }\n\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = null;\n }\n\n this.setState('stopped');\n console.log('AudioInputService 已停止');\n }\n\n /**\n * 获取当前状态\n * Get current state\n */\n getState(): AudioInputState {\n return this.state;\n }\n\n /**\n * 获取配置\n * Get configuration\n */\n getConfig(): Required<AudioInputConfig> {\n return { ...this.config };\n }\n\n /**\n * 获取音频上下文\n * Get audio context\n */\n getAudioContext(): AudioContext | null {\n return this.audioContext;\n }\n\n /**\n * 获取分析器节点\n * Get analyser node\n */\n getAnalyserNode(): AnalyserNode | null {\n return this.analyserNode;\n }\n\n /**\n * 设置状态\n * Set state\n */\n private setState(state: AudioInputState): void {\n this.state = state;\n }\n\n /**\n * 检查是否正在运行\n * Check if running\n */\n isRunning(): boolean {\n return this.state === 'active';\n }\n}\n\n","/**\n * 音高检测器\n * Pitch Detector\n * \n * 使用自相关算法检测音频中的音高\n * Uses autocorrelation algorithm to detect pitch in audio\n */\n\nimport type { NoteInfo } from '../types';\n\nexport class PitchDetector {\n private sampleRate: number;\n private minFrequency: number;\n private maxFrequency: number;\n\n // 音符名称映射\n private static readonly NOTE_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n\n constructor(sampleRate: number = 44100, minFrequency: number = 27.5, maxFrequency: number = 4186) {\n this.sampleRate = sampleRate;\n this.minFrequency = minFrequency;\n this.maxFrequency = maxFrequency;\n }\n\n /**\n * 检测音高\n * Detect pitch using autocorrelation\n */\n detectPitch(audioBuffer: Float32Array, minVolume: number = 0.01): number | null {\n // 计算RMS音量\n const volume = this.calculateRMS(audioBuffer);\n if (volume < minVolume) {\n return null; // 音量太小,不检测\n }\n\n // 使用自相关算法检测音高\n const frequency = this.autoCorrelate(audioBuffer);\n \n if (frequency === -1 || frequency < this.minFrequency || frequency > this.maxFrequency) {\n return null;\n }\n\n return frequency;\n }\n\n /**\n * 自相关算法\n * Autocorrelation algorithm\n */\n private autoCorrelate(buffer: Float32Array): number {\n const SIZE = buffer.length;\n const MAX_SAMPLES = Math.floor(SIZE / 2);\n let best_offset = -1;\n let best_correlation = 0;\n let rms = 0;\n\n // 计算RMS\n for (let i = 0; i < SIZE; i++) {\n const val = buffer[i];\n if (val !== undefined) {\n rms += val * val;\n }\n }\n rms = Math.sqrt(rms / SIZE);\n\n // 音量太小,不是音符\n if (rms < 0.01) {\n return -1;\n }\n\n // 找到第一个过零点\n let lastCorrelation = 1;\n for (let offset = 0; offset < MAX_SAMPLES; offset++) {\n let correlation = 0;\n\n for (let i = 0; i < MAX_SAMPLES; i++) {\n const val1 = buffer[i];\n const val2 = buffer[i + offset];\n if (val1 !== undefined && val2 !== undefined) {\n correlation += Math.abs(val1 - val2);\n }\n }\n\n correlation = 1 - correlation / MAX_SAMPLES;\n\n if (correlation > 0.9 && correlation > lastCorrelation) {\n const foundGoodCorrelation = correlation > best_correlation;\n if (foundGoodCorrelation) {\n best_correlation = correlation;\n best_offset = offset;\n }\n }\n\n lastCorrelation = correlation;\n }\n\n if (best_correlation > 0.01 && best_offset !== -1) {\n // 使用抛物线插值改进频率估计\n const frequency = this.sampleRate / best_offset;\n return frequency;\n }\n\n return -1;\n }\n\n /**\n * 计算RMS音量\n * Calculate RMS volume\n */\n private calculateRMS(buffer: Float32Array): number {\n let sum = 0;\n for (let i = 0; i < buffer.length; i++) {\n const val = buffer[i];\n if (val !== undefined) {\n sum += val * val;\n }\n }\n return Math.sqrt(sum / buffer.length);\n }\n\n /**\n * 将频率转换为音符信息\n * Convert frequency to note information\n */\n frequencyToNote(frequency: number, volume: number = 1): NoteInfo | null {\n if (frequency <= 0) {\n return null;\n }\n\n // 计算MIDI音符编号\n const midi = Math.round(12 * Math.log2(frequency / 440) + 69);\n \n if (midi < 0 || midi > 127) {\n return null;\n }\n\n // 计算音符名称和八度\n const noteIndex = midi % 12;\n const octave = Math.floor(midi / 12) - 1;\n const noteName = PitchDetector.NOTE_NAMES[noteIndex] || 'C';\n const name = `${noteName}${octave}`;\n\n // 计算标准频率(用于计算置信度)\n const standardFrequency = 440 * Math.pow(2, (midi - 69) / 12);\n const cents = 1200 * Math.log2(frequency / standardFrequency);\n const confidence = Math.max(0, 1 - Math.abs(cents) / 50); // 50音分容差\n\n return {\n name,\n frequency,\n noteName,\n octave,\n midi,\n volume,\n confidence,\n };\n }\n\n /**\n * 使用FFT检测主频率\n * Detect dominant frequency using FFT\n */\n detectDominantFrequency(frequencyData: Float32Array, minVolume: number = -60): number | null {\n const nyquist = this.sampleRate / 2;\n const binWidth = nyquist / frequencyData.length;\n \n let maxIndex = -1;\n let maxValue = -Infinity;\n\n // 只在我们关心的频率范围内搜索\n const minBin = Math.floor(this.minFrequency / binWidth);\n const maxBin = Math.ceil(this.maxFrequency / binWidth);\n\n for (let i = minBin; i < Math.min(maxBin, frequencyData.length); i++) {\n const value = frequencyData[i];\n if (value !== undefined && value > maxValue && value > minVolume) {\n maxValue = value;\n maxIndex = i;\n }\n }\n\n if (maxIndex === -1) {\n return null;\n }\n\n // 使用抛物线插值改进频率估计\n const frequency = this.parabolicInterpolation(frequencyData, maxIndex, binWidth);\n \n return frequency;\n }\n\n /**\n * 抛物线插值\n * Parabolic interpolation for better frequency estimation\n */\n private parabolicInterpolation(data: Float32Array, index: number, binWidth: number): number {\n if (index <= 0 || index >= data.length - 1) {\n return index * binWidth;\n }\n\n const y1 = data[index - 1];\n const y2 = data[index];\n const y3 = data[index + 1];\n\n if (y1 === undefined || y2 === undefined || y3 === undefined) {\n return index * binWidth;\n }\n\n const delta = 0.5 * (y3 - y1) / (2 * y2 - y1 - y3);\n const interpolatedIndex = index + delta;\n\n return interpolatedIndex * binWidth;\n }\n\n /**\n * 检测多个音高(和弦)\n * Detect multiple pitches (chords)\n */\n detectMultiplePitches(frequencyData: Float32Array, minVolume: number = -60): NoteInfo[] {\n const notes: NoteInfo[] = [];\n const nyquist = this.sampleRate / 2;\n const binWidth = nyquist / frequencyData.length;\n \n // 找到所有峰值\n const peaks: { index: number; value: number }[] = [];\n \n for (let i = 1; i < frequencyData.length - 1; i++) {\n const freq = i * binWidth;\n if (freq < this.minFrequency || freq > this.maxFrequency) {\n continue;\n }\n\n const value = frequencyData[i];\n if (value !== undefined && value > minVolume && \n value > (frequencyData[i - 1] ?? -Infinity) && \n value > (frequencyData[i + 1] ?? -Infinity)) {\n peaks.push({ index: i, value });\n }\n }\n\n // 按强度排序,取前5个\n peaks.sort((a, b) => b.value - a.value);\n const topPeaks = peaks.slice(0, 5);\n\n // 转换为音符\n for (const peak of topPeaks) {\n const frequency = this.parabolicInterpolation(frequencyData, peak.index, binWidth);\n \n // 计算相对音量(归一化到0-1)\n const volume = Math.pow(10, peak.value / 20); // 从dB转换\n \n const note = this.frequencyToNote(frequency, volume);\n if (note) {\n notes.push(note);\n }\n }\n\n return notes;\n }\n}\n\n","/**\n * 和弦识别器\n * Chord Recognizer\n * \n * 根据检测到的音符识别和弦\n * Recognizes chords based on detected notes\n */\n\nimport type { NoteInfo, ChordInfo } from '../types';\n\ninterface ChordPattern {\n name: string;\n intervals: number[]; // 相对于根音的半音数\n aliases?: string[];\n}\n\nexport class ChordRecognizer {\n // 和弦模式定义\n private static readonly CHORD_PATTERNS: ChordPattern[] = [\n // 三和弦\n { name: 'major', intervals: [0, 4, 7], aliases: ['maj', 'M'] },\n { name: 'minor', intervals: [0, 3, 7], aliases: ['min', 'm'] },\n { name: 'diminished', intervals: [0, 3, 6], aliases: ['dim', '°'] },\n { name: 'augmented', intervals: [0, 4, 8], aliases: ['aug', '+'] },\n { name: 'sus2', intervals: [0, 2, 7] },\n { name: 'sus4', intervals: [0, 5, 7] },\n \n // 七和弦\n { name: 'major7', intervals: [0, 4, 7, 11], aliases: ['maj7', 'M7'] },\n { name: 'minor7', intervals: [0, 3, 7, 10], aliases: ['min7', 'm7'] },\n { name: 'dominant7', intervals: [0, 4, 7, 10], aliases: ['7'] },\n { name: 'diminished7', intervals: [0, 3, 6, 9], aliases: ['dim7', '°7'] },\n { name: 'half-diminished7', intervals: [0, 3, 6, 10], aliases: ['m7b5', 'ø7'] },\n { name: 'minor-major7', intervals: [0, 3, 7, 11], aliases: ['mM7', 'm(maj7)'] },\n { name: 'augmented7', intervals: [0, 4, 8, 10], aliases: ['aug7', '+7'] },\n \n // 扩展和弦\n { name: 'major9', intervals: [0, 4, 7, 11, 14], aliases: ['maj9', 'M9'] },\n { name: 'minor9', intervals: [0, 3, 7, 10, 14], aliases: ['min9', 'm9'] },\n { name: 'dominant9', intervals: [0, 4, 7, 10, 14], aliases: ['9'] },\n { name: 'add9', intervals: [0, 4, 7, 14] },\n { name: 'madd9', intervals: [0, 3, 7, 14], aliases: ['m(add9)'] },\n ];\n\n private static readonly NOTE_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n\n /**\n * 识别和弦\n * Recognize chord from notes\n */\n recognizeChord(notes: NoteInfo[]): ChordInfo | null {\n if (notes.length < 2) {\n return null; // 至少需要2个音符才能构成和弦\n }\n\n // 按音高排序\n const sortedNotes = [...notes].sort((a, b) => a.midi - b.midi);\n\n // 去重(相同音符的不同八度)\n const uniqueNoteClasses = this.getUniqueNoteClasses(sortedNotes);\n \n if (uniqueNoteClasses.length < 2) {\n return null;\n }\n\n // 尝试所有可能的根音\n let bestMatch: { root: string; pattern: ChordPattern; confidence: number } | null = null;\n\n for (let i = 0; i < uniqueNoteClasses.length; i++) {\n const root = uniqueNoteClasses[i];\n if (!root) continue; // 跳过 undefined\n \n const intervals = this.calculateIntervals(root, uniqueNoteClasses);\n \n // 匹配和弦模式\n for (const pattern of ChordRecognizer.CHORD_PATTERNS) {\n const confidence = this.matchPattern(intervals, pattern.intervals);\n \n if (confidence > 0.8 && (!bestMatch || confidence > bestMatch.confidence)) {\n bestMatch = { root, pattern, confidence };\n }\n }\n }\n\n if (!bestMatch) {\n return null;\n }\n\n // 构建和弦信息\n const chordName = `${bestMatch.root}${this.getChordSuffix(bestMatch.pattern)}`;\n \n return {\n name: chordName,\n root: bestMatch.root,\n type: bestMatch.pattern.name,\n notes: sortedNotes,\n confidence: bestMatch.confidence,\n };\n }\n\n /**\n * 获取唯一的音符类别(不考虑八度)\n * Get unique note classes (ignoring octave)\n */\n private getUniqueNoteClasses(notes: NoteInfo[]): string[] {\n const noteSet = new Set<string>();\n for (const note of notes) {\n noteSet.add(note.noteName);\n }\n return Array.from(noteSet);\n }\n\n /**\n * 计算音程\n * Calculate intervals from root\n */\n private calculateIntervals(root: string, noteClasses: string[]): number[] {\n const rootIndex = ChordRecognizer.NOTE_NAMES.indexOf(root);\n const intervals: number[] = [];\n\n for (const noteClass of noteClasses) {\n const noteIndex = ChordRecognizer.NOTE_NAMES.indexOf(noteClass);\n let interval = (noteIndex - rootIndex + 12) % 12;\n intervals.push(interval);\n }\n\n return intervals.sort((a, b) => a - b);\n }\n\n /**\n * 匹配和弦模式\n * Match chord pattern\n */\n private matchPattern(intervals: number[], pattern: number[]): number {\n if (intervals.length < pattern.length) {\n return 0;\n }\n\n let matches = 0;\n for (const patternInterval of pattern) {\n if (intervals.includes(patternInterval)) {\n matches++;\n }\n }\n\n // 计算匹配度\n const precision = matches / pattern.length;\n const recall = matches / intervals.length;\n \n // 使用F1分数\n if (precision + recall === 0) {\n return 0;\n }\n \n return (2 * precision * recall) / (precision + recall);\n }\n\n /**\n * 获取和弦后缀\n * Get chord suffix for display\n */\n private getChordSuffix(pattern: ChordPattern): string {\n // 使用最短的别名或原名称\n if (pattern.aliases && pattern.aliases.length > 0) {\n return pattern.aliases[0] || '';\n }\n \n // 转换常见名称\n const suffixMap: { [key: string]: string } = {\n 'major': '',\n 'minor': 'm',\n 'diminished': 'dim',\n 'augmented': 'aug',\n 'dominant7': '7',\n };\n \n return suffixMap[pattern.name] ?? pattern.name;\n }\n\n /**\n * 识别八度内的音程(用于简单的音程识别)\n * Recognize interval within an octave\n */\n recognizeInterval(note1: NoteInfo, note2: NoteInfo): string {\n const semitones = Math.abs(note1.midi - note2.midi) % 12;\n \n const intervalNames: { [key: number]: string } = {\n 0: '纯一度 (Unison)',\n 1: '小二度 (Minor 2nd)',\n 2: '大二度 (Major 2nd)',\n 3: '小三度 (Minor 3rd)',\n 4: '大三度 (Major 3rd)',\n 5: '纯四度 (Perfect 4th)',\n 6: '增四度/减五度 (Tritone)',\n 7: '纯五度 (Perfect 5th)',\n 8: '小六度 (Minor 6th)',\n 9: '大六度 (Major 6th)',\n 10: '小七度 (Minor 7th)',\n 11: '大七度 (Major 7th)',\n };\n \n return intervalNames[semitones] || '未知音程';\n }\n\n /**\n * 分析和弦质量\n * Analyze chord quality\n */\n analyzeChordQuality(chord: ChordInfo): string {\n const qualities: string[] = [];\n \n if (chord.type.includes('major')) {\n qualities.push('大调');\n } else if (chord.type.includes('minor')) {\n qualities.push('小调');\n }\n \n if (chord.type.includes('diminished')) {\n qualities.push('减');\n } else if (chord.type.includes('augmented')) {\n qualities.push('增');\n }\n \n if (chord.type.includes('7')) {\n qualities.push('七和弦');\n } else if (chord.type.includes('9')) {\n qualities.push('九和弦');\n }\n \n if (chord.type.includes('sus')) {\n qualities.push('挂留');\n }\n \n return qualities.join(' ') || '基础和弦';\n }\n}\n\n","/**\n * 音频检测器 - 主控制器\n * Audio Detector - Main Controller\n * \n * 整合音频输入、音高检测和和弦识别\n * Integrates audio input, pitch detection, and chord recognition\n */\n\nimport { AudioInputService } from './AudioInputService';\nimport { PitchDetector } from './PitchDetector';\nimport { ChordRecognizer } from './ChordRecognizer';\nimport type { \n AudioInputConfig, \n AudioDetectionResult, \n AudioDetectorEvents,\n AudioInputState,\n NoteInfo,\n ChordInfo,\n} from '../types';\n\nexport class AudioDetector {\n private audioInput: AudioInputService;\n private pitchDetector: PitchDetector;\n private chordRecognizer: ChordRecognizer;\n private isDetecting: boolean = false;\n private animationFrameId: number | null = null;\n private events: AudioDetectorEvents;\n private lastResult: AudioDetectionResult | null = null;\n\n constructor(config: AudioInputConfig = {}, events: AudioDetectorEvents = {}) {\n this.audioInput = new AudioInputService(config);\n const audioConfig = this.audioInput.getConfig();\n \n this.pitchDetector = new PitchDetector(\n audioConfig.sampleRate,\n audioConfig.frequencyRange.min,\n audioConfig.frequencyRange.max\n );\n \n this.chordRecognizer = new ChordRecognizer();\n this.events = events;\n }\n\n /**\n * 启动音频检测\n * Start audio detection\n */\n async start(): Promise<void> {\n if (this.isDetecting) {\n console.warn('AudioDetector 已经在运行');\n return;\n }\n\n try {\n // 初始化音频输入\n await this.audioInput.initialize();\n \n // 通知状态变化\n this.events.onStateChange?.('active');\n \n // 开始检测循环\n this.isDetecting = true;\n this.detectLoop();\n \n console.log('AudioDetector 已启动');\n } catch (error) {\n this.events.onStateChange?.('error');\n this.events.onError?.(error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n\n /**\n * 停止音频检测\n * Stop audio detection\n */\n stop(): void {\n if (!this.isDetecting) {\n return;\n }\n\n this.isDetecting = false;\n \n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n\n this.audioInput.stop();\n this.events.onStateChange?.('stopped');\n \n console.log('AudioDetector 已停止');\n }\n\n /**\n * 检测循环\n * Detection loop\n */\n private detectLoop = (): void => {\n if (!this.isDetecting) {\n return;\n }\n\n try {\n const result = this.detect();\n \n if (result) {\n this.lastResult = result;\n this.events.onDetection?.(result);\n }\n } catch (error) {\n console.error('检测过程中出错:', error);\n this.events.onError?.(error instanceof Error ? error : new Error(String(error)));\n }\n\n // 继续下一帧\n this.animationFrameId = requestAnimationFrame(this.detectLoop);\n };\n\n /**\n * 执行一次检测\n * Perform single detection\n */\n private detect(): AudioDetectionResult | null {\n const config = this.audioInput.getConfig();\n\n // 获取时域数据(用于自相关)\n const timeDomainData = this.audioInput.getTimeDomainData();\n \n // 获取频域数据(用于多音检测)\n const frequencyData = this.audioInput.getFrequencyData();\n \n // 获取当前音量\n const volume = this.audioInput.getCurrentVolume();\n\n // 调试日志:每2秒输出一次音量信息\n if (Date.now() % 2000 < 100) {\n console.log(`[AudioDetector] 当前音量: ${volume.toFixed(6)}, 阈值: ${config.minVolume}, 状态: ${volume >= config.minVolume ? '✅ 有声音' : '❌ 音量太低'}`);\n }\n\n // 检查是否有足够的音量\n if (volume < config.minVolume) {\n return {\n notes: [],\n timestamp: Date.now(),\n isDetecting: false,\n };\n }\n\n // 方法1: 使用时域自相关检测主音高\n const dominantFrequency = this.pitchDetector.detectPitch(timeDomainData, config.minVolume);\n \n // 方法2: 使用频域检测多个音高\n const detectedNotes = this.pitchDetector.detectMultiplePitches(frequencyData, -60);\n \n // 如果时域检测到了主音高,确保它在结果中\n if (dominantFrequency && dominantFrequency > 0) {\n const dominantNote = this.pitchDetector.frequencyToNote(dominantFrequency, volume);\n if (dominantNote) {\n // 检查是否已经在列表中\n const exists = detectedNotes.some(n => Math.abs(n.midi - dominantNote.midi) < 1);\n if (!exists) {\n detectedNotes.unshift(dominantNote);\n }\n }\n }\n\n // 过滤掉置信度太低的音符\n const filteredNotes = detectedNotes.filter(note => note.confidence >= config.minConfidence);\n\n // 识别和弦\n let chord: ChordInfo | undefined;\n if (filteredNotes.length >= 2) {\n chord = this.chordRecognizer.recognizeChord(filteredNotes) ?? undefined;\n }\n\n return {\n notes: filteredNotes,\n chord,\n timestamp: Date.now(),\n isDetecting: filteredNotes.length > 0,\n };\n }\n\n /**\n * 获取当前状态\n * Get current state\n */\n getState(): AudioInputState {\n return this.audioInput.getState();\n }\n\n /**\n * 获取最后的检测结果\n * Get last detection result\n */\n getLastResult(): AudioDetectionResult | null {\n return this.lastResult;\n }\n\n /**\n * 检查是否正在运行\n * Check if running\n */\n isRunning(): boolean {\n return this.isDetecting && this.audioInput.isRunning();\n }\n\n /**\n * 获取音频输入服务\n * Get audio input service\n */\n getAudioInput(): AudioInputService {\n return this.audioInput;\n }\n}\n\n","/**\n * 音频检测调试工具\n * Audio Detection Debug Tool\n */\n\nimport { AudioDetector } from './AudioDetector';\nimport type { AudioInputConfig } from '../types';\n\nexport class AudioDetectorDebugger {\n private detector: AudioDetector;\n private debugInterval: number | null = null;\n\n constructor(config: AudioInputConfig = {}) {\n this.detector = new AudioDetector(config, {\n onDetection: (result) => {\n if (result.isDetecting) {\n console.log('🎵 检测到音符:', result.notes.map(n => `${n.name}(${n.frequency.toFixed(1)}Hz)`).join(', '));\n if (result.chord) {\n console.log('🎹 检测到和弦:', result.chord.name);\n }\n }\n },\n onStateChange: (state) => {\n console.log('📊 状态变化:', state);\n },\n onError: (error) => {\n console.error('❌ 错误:', error);\n },\n });\n }\n\n async start(): Promise<void> {\n await this.detector.start();\n \n // 启动调试信息输出\n this.debugInterval = window.setInterval(() => {\n const audioInput = this.detector.getAudioInput();\n const volume = audioInput.getCurrentVolume();\n const config = audioInput.getConfig();\n const analyser = audioInput.getAnalyserNode();\n \n if (analyser) {\n // 获取频域数据\n const freqData = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(freqData);\n \n // 找到最大值\n let maxFreqValue = -Infinity;\n for (let i = 0; i < freqData.length; i++) {\n const val = freqData[i];\n if (val !== undefined && val > maxFreqValue) {\n maxFreqValue = val;\n }\n }\n \n console.log(`\n🎤 音频调试信息:\n - 音量 (RMS): ${volume.toFixed(6)}\n - 音量阈值: ${config.minVolume}\n - 音量状态: ${volume >= config.minVolume ? '✅ 超过阈值' : '❌ 低于阈值'}\n - 最大频率强度: ${maxFreqValue.toFixed(2)} dB\n - 采样率: ${config.sampleRate} Hz\n - FFT大小: ${config.fftSize}\n - 平滑系数: ${config.smoothing}\n `);\n }\n }, 2000);\n }\n\n stop(): void {\n if (this.debugInterval !== null) {\n clearInterval(this.debugInterval);\n this.debugInterval = null;\n }\n this.detector.stop();\n }\n\n getDetector(): AudioDetector {\n return this.detector;\n }\n\n /**\n * 测试麦克风是否正常工作\n */\n async testMicrophone(): Promise<{\n hasPermission: boolean;\n isReceivingAudio: boolean;\n averageVolume: number;\n peakVolume: number;\n }> {\n console.log('🔍 开始测试麦克风...');\n \n await this.detector.start();\n \n // 收集5秒的音量数据\n const volumes: number[] = [];\n const audioInput = this.detector.getAudioInput();\n \n return new Promise((resolve) => {\n const sampleInterval = setInterval(() => {\n volumes.push(audioInput.getCurrentVolume());\n }, 100);\n \n setTimeout(() => {\n clearInterval(sampleInterval);\n \n const averageVolume = volumes.reduce((a, b) => a + b, 0) / volumes.length;\n const peakVolume = Math.max(...volumes);\n const isReceivingAudio = peakVolume > 0.0001;\n \n console.log(`\n✅ 麦克风测试完成:\n - 权限状态: ✅ 已授权\n - 接收音频: ${isReceivingAudio ? '✅ 是' : '❌ 否'}\n - 平均音量: ${averageVolume.toFixed(6)}\n - 峰值音量: ${peakVolume.toFixed(6)}\n - 建议阈值: ${(peakVolume * 0.1).toFixed(6)}\n `);\n \n resolve({\n hasPermission: true,\n isReceivingAudio,\n averageVolume,\n peakVolume,\n });\n }, 5000);\n });\n }\n}\n\n// 导出便捷函数\nexport async function debugAudioDetection(config?: AudioInputConfig): Promise<AudioDetectorDebugger> {\n const dbg = new AudioDetectorDebugger(config);\n await dbg.start();\n return dbg;\n}\n\nexport async function testMicrophone(): Promise<void> {\n const dbg = new AudioDetectorDebugger();\n await dbg.testMicrophone();\n dbg.stop();\n}\n\n","/**\n * 音频检测 React Hook\n * Audio Detection React Hook\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { AudioDetector } from '../core/AudioDetector';\nimport type { \n AudioInputConfig, \n AudioDetectionResult, \n AudioInputState,\n} from '../types';\n\nexport interface UseAudioDetectionOptions extends AudioInputConfig {\n /** 是否自动开始检测 */\n autoStart?: boolean;\n /** 检测结果更新间隔(毫秒) */\n updateInterval?: number;\n}\n\nexport interface UseAudioDetectionReturn {\n /** 当前检测结果 */\n result: AudioDetectionResult | null;\n /** 音频输入状态 */\n state: AudioInputState;\n /** 是否正在检测 */\n isDetecting: boolean;\n /** 错误信息 */\n error: Error | null;\n /** 启动检测 */\n start: () => Promise<void>;\n /** 停止检测 */\n stop: () => void;\n /** 获取检测器实例 */\n getDetector: () => AudioDetector | null;\n}\n\n/**\n * 使用音频检测的 Hook\n * Hook for using audio detection\n */\nexport function useAudioDetection(options: UseAudioDetectionOptions = {}): UseAudioDetectionReturn {\n const { autoStart = false, updateInterval = 100, ...config } = options;\n \n const [result, setResult] = useState<AudioDetectionResult | null>(null);\n const [state, setState] = useState<AudioInputState>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [isDetecting, setIsDetecting] = useState(false);\n \n const detectorRef = useRef<AudioDetector | null>(null);\n const lastUpdateRef = useRef<number>(0);\n\n // 初始化检测器\n useEffect(() => {\n const detector = new AudioDetector(config, {\n onDetection: (detectionResult) => {\n // 限制更新频率\n const now = Date.now();\n if (now - lastUpdateRef.current >= updateInterval) {\n setResult(detectionResult);\n lastUpdateRef.current = now;\n }\n },\n onStateChange: (newState) => {\n setState(newState);\n },\n onError: (err) => {\n setError(err);\n setIsDetecting(false);\n },\n });\n\n detectorRef.current = detector;\n\n // 自动启动\n if (autoStart) {\n detector.start().catch((err) => {\n setError(err);\n });\n setIsDetecting(true);\n }\n\n // 清理\n return () => {\n if (detector.isRunning()) {\n detector.stop();\n }\n };\n }, []); // 只在挂载时初始化\n\n // 启动检测\n const start = useCallback(async () => {\n if (!detectorRef.current) {\n const err = new Error('检测器未初始化');\n setError(err);\n throw err;\n }\n\n try {\n setError(null);\n await detectorRef.current.start();\n setIsDetecting(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setIsDetecting(false);\n throw error;\n }\n }, []);\n\n // 停止检测\n const stop = useCallback(() => {\n if (detectorRef.current) {\n detectorRef.current.stop();\n setIsDetecting(false);\n setResult(null);\n }\n }, []);\n\n // 获取检测器实例\n const getDetector = useCallback(() => {\n return detectorRef.current;\n }, []);\n\n return {\n result,\n state,\n isDetecting,\n error,\n start,\n stop,\n getDetector,\n };\n}\n\n","/**\n * 音频检测组件\n * Audio Detection Component\n * \n * 显示实时音频检测结果的React组件\n * React component for displaying real-time audio detection results\n */\n\nimport React from 'react';\nimport { useAudioDetection, type UseAudioDetectionOptions } from '../hooks/useAudioDetection';\nimport type { NoteInfo, ChordInfo } from '../types';\n\nexport interface AudioDetectionDisplayProps extends UseAudioDetectionOptions {\n /** 自定义类名 */\n className?: string;\n /** 是否显示调试信息 */\n showDebugInfo?: boolean;\n /** 自定义渲染音符 */\n renderNote?: (note: NoteInfo) => React.ReactNode;\n /** 自定义渲染和弦 */\n renderChord?: (chord: ChordInfo) => React.ReactNode;\n /** 开始按钮文本 */\n startButtonText?: string;\n /** 停止按钮文本 */\n stopButtonText?: string;\n}\n\n/**\n * 音频检测显示组件\n */\nexport const AudioDetectionDisplay: React.FC<AudioDetectionDisplayProps> = ({\n className = '',\n showDebugInfo = false,\n renderNote,\n renderChord,\n startButtonText = '开始检测',\n stopButtonText = '停止检测',\n ...options\n}) => {\n const { result, state, isDetecting, error, start, stop } = useAudioDetection(options);\n\n const handleToggle = async () => {\n if (isDetecting) {\n stop();\n } else {\n try {\n await start();\n } catch (err) {\n console.error('启动失败:', err);\n }\n }\n };\n\n return (\n <div className={`audio-detection-display ${className}`}>\n {/* 控制按钮 */}\n <div className=\"audio-detection-controls\">\n <button\n onClick={handleToggle}\n disabled={state === 'initializing'}\n className={`audio-detection-button ${isDetecting ? 'active' : ''}`}\n >\n {state === 'initializing' ? '初始化中...' : isDetecting ? stopButtonText : startButtonText}\n </button>\n \n <div className={`audio-detection-status status-${state}`}>\n 状态: {getStateLabel(state)}\n </div>\n </div>\n\n {/* 错误信息 */}\n {error && (\n <div className=\"audio-detection-error\">\n <strong>错误:</strong> {error.message}\n </div>\n )}\n\n {/* 检测结果 */}\n {result && result.isDetecting && (\n <div className=\"audio-detection-result\">\n {/* 音符显示 */}\n {result.notes.length > 0 && (\n <div className=\"audio-detection-notes\">\n <h3>检测到的音符:</h3>\n <div className=\"notes-grid\">\n {result.notes.map((note, index) => (\n <div key={index} className=\"note-item\">\n {renderNote ? renderNote(note) : <DefaultNoteDisplay note={note} />}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* 和弦显示 */}\n {result.chord && (\n <div className=\"audio-detection-chord\">\n <h3>识别的和弦:</h3>\n {renderChord ? renderChord(result.chord) : <DefaultChordDisplay chord={result.chord} />}\n </div>\n )}\n\n {/* 调试信息 */}\n {showDebugInfo && (\n <div className=\"audio-detection-debug\">\n <h4>调试信息:</h4>\n <pre>{JSON.stringify(result, null, 2)}</pre>\n </div>\n )}\n </div>\n )}\n\n {/* 无检测结果时的提示 */}\n {isDetecting && (!result || !result.isDetecting) && (\n <div className=\"audio-detection-waiting\">\n 正在监听... 请弹奏电子琴\n </div>\n )}\n </div>\n );\n};\n\n/**\n * 默认音符显示\n */\nconst DefaultNoteDisplay: React.FC<{ note: NoteInfo }> = ({ note }) => (\n <div className=\"default-note-display\">\n <div className=\"note-name\">{note.name}</div>\n <div className=\"note-frequency\">{note.frequency.toFixed(2)} Hz</div>\n <div className=\"note-confidence\">\n 置信度: {(note.confidence * 100).toFixed(0)}%\n </div>\n </div>\n);\n\n/**\n * 默认和弦显示\n */\nconst DefaultChordDisplay: React.FC<{ chord: ChordInfo }> = ({ chord }) => (\n <div className=\"default-chord-display\">\n <div className=\"chord-name\">{chord.name}</div>\n <div className=\"chord-type\">类型: {chord.type}</div>\n <div className=\"chord-notes\">\n 音符: {chord.notes.map(n => n.name).join(', ')}\n </div>\n <div className=\"chord-confidence\">\n 置信度: {(chord.confidence * 100).toFixed(0)}%\n </div>\n </div>\n);\n\n/**\n * 获取状态标签\n */\nfunction getStateLabel(state: string): string {\n const labels: { [key: string]: string } = {\n idle: '空闲',\n initializing: '初始化中',\n active: '运行中',\n error: '错误',\n stopped: '已停止',\n };\n return labels[state] || state;\n}\n\n/**\n * 默认样式(可以通过CSS覆盖)\n */\nexport const audioDetectionStyles = `\n.audio-detection-display {\n padding: 20px;\n border: 1px solid #ddd;\n border-radius: 8px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.audio-detection-controls {\n display: flex;\n gap: 12px;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.audio-detection-button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n border-radius: 6px;\n background-color: #007bff;\n color: white;\n cursor: pointer;\n transition: background-color 0.3s;\n}\n\n.audio-detection-button:hover {\n background-color: #0056b3;\n}\n\n.audio-detection-button:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.audio-detection-button.active {\n background-color: #dc3545;\n}\n\n.audio-detection-button.active:hover {\n background-color: #c82333;\n}\n\n.audio-detection-status {\n padding: 8px 16px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.status-idle { background-color: #e7f3ff; color: #004085; }\n.status-initializing { background-color: #fff3cd; color: #856404; }\n.status-active { background-color: #d4edda; color: #155724; }\n.status-error { background-color: #f8d7da; color: #721c24; }\n.status-stopped { background-color: #e2e3e5; color: #383d41; }\n\n.audio-detection-error {\n padding: 12px;\n background-color: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 4px;\n color: #721c24;\n margin-bottom: 16px;\n}\n\n.audio-detection-result {\n margin-top: 20px;\n}\n\n.audio-detection-notes h3,\n.audio-detection-chord h3 {\n margin-bottom: 12px;\n font-size: 18px;\n}\n\n.notes-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n}\n\n.note-item {\n padding: 12px;\n border: 2px solid #007bff;\n border-radius: 6px;\n background-color: #f8f9fa;\n}\n\n.default-note-display {\n text-align: center;\n}\n\n.note-name {\n font-size: 24px;\n font-weight: bold;\n color: #007bff;\n margin-bottom: 4px;\n}\n\n.note-frequency {\n font-size: 14px;\n color: #666;\n margin-bottom: 4px;\n}\n\n.note-confidence {\n font-size: 12px;\n color: #999;\n}\n\n.audio-detection-chord {\n margin-top: 20px;\n padding: 16px;\n border: 2px solid #28a745;\n border-radius: 8px;\n background-color: #f8f9fa;\n}\n\n.default-chord-display {\n text-align: center;\n}\n\n.chord-name {\n font-size: 32px;\n font-weight: bold;\n color: #28a745;\n margin-bottom: 8px;\n}\n\n.chord-type,\n.chord-notes,\n.chord-confidence {\n margin-bottom: 4px;\n color: #666;\n}\n\n.audio-detection-waiting {\n text-align: center;\n padding: 40px;\n color: #666;\n font-size: 18px;\n}\n\n.audio-detection-debug {\n margin-top: 20px;\n padding: 12px;\n background-color: #f4f4f4;\n border-radius: 4px;\n}\n\n.audio-detection-debug pre {\n margin: 8px 0 0 0;\n font-size: 12px;\n overflow-x: auto;\n}\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","/**\n * 钢琴键盘可视化组件\n * Piano Keyboard Visualization Component\n */\n\nimport React, { useMemo } from 'react';\nimport type { NoteInfo } from '../types';\n\nexport interface PianoKeyboardProps {\n /** 当前激活的音符 */\n activeNotes?: NoteInfo[];\n /** 起始八度 (默认: 2) */\n startOctave?: number;\n /** 结束八度 (默认: 6) */\n endOctave?: number;\n /** 自定义类名 */\n className?: string;\n /** 是否显示音符名称 */\n showNoteNames?: boolean;\n}\n\ninterface PianoKey {\n noteName: string;\n octave: number;\n midi: number;\n isBlack: boolean;\n isActive: boolean;\n}\n\n/**\n * 钢琴键盘可视化\n */\nexport const PianoKeyboard: React.FC<PianoKeyboardProps> = ({\n activeNotes = [],\n startOctave = 2,\n endOctave = 6,\n className = '',\n showNoteNames = true,\n}) => {\n // 生成钢琴键\n const keys = useMemo(() => {\n const noteNames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n const blackKeys = new Set(['C#', 'D#', 'F#', 'G#', 'A#']);\n const allKeys: PianoKey[] = [];\n\n for (let octave = startOctave; octave <= endOctave; octave++) {\n for (const noteName of noteNames) {\n const midi = (octave + 1) * 12 + noteNames.indexOf(noteName);\n const isActive = activeNotes.some(note => note.midi === midi);\n \n allKeys.push({\n noteName,\n octave,\n midi,\n isBlack: blackKeys.has(noteName),\n isActive,\n });\n }\n }\n\n return allKeys;\n }, [startOctave, endOctave, activeNotes]);\n\n // 分离白键和黑键\n const whiteKeys = keys.filter(k => !k.isBlack);\n const blackKeys = keys.filter(k => k.isBlack);\n\n return (\n <div className={`piano-keyboard ${className}`}>\n <div className=\"piano-keys-container\">\n {/* 白键 */}\n <div className=\"white-keys\">\n {whiteKeys.map((key, index) => (\n <div\n key={`white-${key.midi}`}\n className={`piano-key white-key ${key.isActive ? 'active' : ''}`}\n title={`${key.noteName}${key.octave}`}\n >\n {showNoteNames && (\n <span className=\"key-label\">{key.noteName}{key.octave}</span>\n )}\n </div>\n ))}\n </div>\n\n {/* 黑键 */}\n <div className=\"black-keys\">\n {blackKeys.map((key) => {\n // 计算黑键的位置\n const whiteKeyIndex = getWhiteKeyIndexBeforeBlack(key.noteName);\n const octaveOffset = (key.octave - startOctave) * 7; // 每个八度有7个白键\n const position = whiteKeyIndex + octaveOffset;\n\n return (\n <div\n key={`black-${key.midi}`}\n className={`piano-key black-key ${key.isActive ? 'active' : ''}`}\n style={{ left: `${(position + 0.7) * (100 / whiteKeys.length)}%` }}\n title={`${key.noteName}${key.octave}`}\n >\n {showNoteNames && (\n <span className=\"key-label\">{key.noteName}{key.octave}</span>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * 获取黑键之前的白键索引\n */\nfunction getWhiteKeyIndexBeforeBlack(noteName: string): number {\n const map: { [key: string]: number } = {\n 'C#': 0,\n 'D#': 1,\n 'F#': 3,\n 'G#': 4,\n 'A#': 5,\n };\n return map[noteName] || 0;\n}\n\n/**\n * 钢琴键盘样式\n */\nexport const pianoKeyboardStyles = `\n.piano-keyboard {\n width: 100%;\n padding: 20px;\n background-color: #2c3e50;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n}\n\n.piano-keys-container {\n position: relative;\n width: 100%;\n height: 200px;\n}\n\n.white-keys {\n display: flex;\n height: 100%;\n gap: 2px;\n}\n\n.piano-key {\n position: relative;\n border: 1px solid #000;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.white-key {\n flex: 1;\n background: linear-gradient(to bottom, #ffffff 0%, #f0f0f0 100%);\n border-radius: 0 0 4px 4px;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 8px;\n}\n\n.white-key:hover {\n background: linear-gradient(to bottom, #f8f8f8 0%, #e8e8e8 100%);\n}\n\n.white-key.active {\n background: linear-gradient(to bottom, #4CAF50 0%, #45a049 100%) !important;\n box-shadow: 0 0 20px rgba(76, 175, 80, 0.8);\n}\n\n.black-keys {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 60%;\n pointer-events: none;\n}\n\n.black-key {\n position: absolute;\n width: calc(100% / 52 * 0.6); /* 假设有52个白键的宽度 */\n height: 100%;\n background: linear-gradient(to bottom, #2c3e50 0%, #1a252f 100%);\n border-radius: 0 0 3px 3px;\n pointer-events: all;\n transform: translateX(-50%);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 6px;\n z-index: 10;\n}\n\n.black-key:hover {\n background: linear-gradient(to bottom, #34495e 0%, #2c3e50 100%);\n}\n\n.black-key.active {\n background: linear-gradient(to bottom, #4CAF50 0%, #388E3C 100%) !important;\n box-shadow: 0 0 20px rgba(76, 175, 80, 0.8);\n}\n\n.key-label {\n font-size: 11px;\n font-weight: bold;\n user-select: none;\n}\n\n.white-key .key-label {\n color: #666;\n}\n\n.white-key.active .key-label {\n color: white;\n}\n\n.black-key .key-label {\n color: #ddd;\n}\n\n.black-key.active .key-label {\n color: white;\n}\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/audioDetection/core/AudioInputService.ts","../../src/audioDetection/core/PitchDetector.ts","../../src/audioDetection/core/ChordRecognizer.ts","../../src/audioDetection/core/AudioDetector.ts","../../src/audioDetection/core/AudioDetectorDebugger.ts","../../src/audioDetection/hooks/useAudioDetection.ts","../../src/audioDetection/components/AudioDetectionDisplay.tsx","../../src/audioDetection/components/PianoKeyboard.tsx"],"names":["useState","useRef","useEffect","useCallback","error","React","useMemo","blackKeys"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 音频输入服务\n * Audio Input Service\n * \n * 负责管理麦克风输入和音频流处理\n * Manages microphone input and audio stream processing\n */\n\nimport type { AudioInputConfig, AudioInputState } from '../types';\n\nexport class AudioInputService {\n private audioContext: AudioContext | null = null;\n private mediaStream: MediaStream | null = null;\n private sourceNode: MediaStreamAudioSourceNode | null = null;\n private analyserNode: AnalyserNode | null = null;\n private state: AudioInputState = 'idle';\n private config: Required<AudioInputConfig>;\n\n constructor(config: AudioInputConfig = {}) {\n this.config = {\n sampleRate: config.sampleRate ?? 44100,\n fftSize: config.fftSize ?? 4096,\n minVolume: config.minVolume ?? 0.001, // 降低默认阈值,使其更敏感\n minConfidence: config.minConfidence ?? 0.5, // 降低默认置信度,更容易检测\n smoothing: config.smoothing ?? 0.8,\n frequencyRange: config.frequencyRange ?? { min: 27.5, max: 4186 }, // A0 到 C8\n };\n }\n\n /**\n * 初始化音频输入\n * Initialize audio input\n */\n async initialize(): Promise<void> {\n if (this.state === 'active') {\n console.warn('AudioInputService 已经处于活动状态');\n return;\n }\n\n try {\n this.setState('initializing');\n\n // 请求麦克风权限\n this.mediaStream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: false,\n noiseSuppression: false,\n autoGainControl: false,\n sampleRate: this.config.sampleRate,\n },\n });\n\n // 创建音频上下文\n this.audioContext = new AudioContext({\n sampleRate: this.config.sampleRate,\n });\n\n // 创建音频源节点\n this.sourceNode = this.audioContext.createMediaStreamSource(this.mediaStream);\n\n // 创建分析器节点\n this.analyserNode = this.audioContext.createAnalyser();\n this.analyserNode.fftSize = this.config.fftSize;\n this.analyserNode.smoothingTimeConstant = this.config.smoothing;\n\n // 连接节点\n this.sourceNode.connect(this.analyserNode);\n\n this.setState('active');\n console.log('AudioInputService 初始化成功');\n } catch (error) {\n this.setState('error');\n console.error('AudioInputService 初始化失败:', error);\n throw new Error(`麦克风初始化失败: ${error instanceof Error ? error.message : '未知错误'}`);\n }\n }\n\n /**\n * 获取时域数据\n * Get time domain data\n */\n getTimeDomainData(): Float32Array {\n if (!this.analyserNode) {\n throw new Error('AnalyserNode 未初始化');\n }\n\n const bufferLength = this.analyserNode.fftSize;\n const dataArray = new Float32Array(bufferLength);\n this.analyserNode.getFloatTimeDomainData(dataArray);\n return dataArray;\n }\n\n /**\n * 获取频域数据\n * Get frequency domain data\n */\n getFrequencyData(): Float32Array {\n if (!this.analyserNode) {\n throw new Error('AnalyserNode 未初始化');\n }\n\n const bufferLength = this.analyserNode.frequencyBinCount;\n const dataArray = new Float32Array(bufferLength);\n this.analyserNode.getFloatFrequencyData(dataArray);\n return dataArray;\n }\n\n /**\n * 获取当前音量\n * Get current volume\n */\n getCurrentVolume(): number {\n const timeDomainData = this.getTimeDomainData();\n let sum = 0;\n for (let i = 0; i < timeDomainData.length; i++) {\n const val = timeDomainData[i];\n if (val !== undefined) {\n sum += val * val;\n }\n }\n return Math.sqrt(sum / timeDomainData.length);\n }\n\n /**\n * 停止音频输入\n * Stop audio input\n */\n stop(): void {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach(track => track.stop());\n this.mediaStream = null;\n }\n\n if (this.sourceNode) {\n this.sourceNode.disconnect();\n this.sourceNode = null;\n }\n\n if (this.analyserNode) {\n this.analyserNode.disconnect();\n this.analyserNode = null;\n }\n\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = null;\n }\n\n this.setState('stopped');\n console.log('AudioInputService 已停止');\n }\n\n /**\n * 获取当前状态\n * Get current state\n */\n getState(): AudioInputState {\n return this.state;\n }\n\n /**\n * 获取配置\n * Get configuration\n */\n getConfig(): Required<AudioInputConfig> {\n return { ...this.config };\n }\n\n /**\n * 获取音频上下文\n * Get audio context\n */\n getAudioContext(): AudioContext | null {\n return this.audioContext;\n }\n\n /**\n * 获取分析器节点\n * Get analyser node\n */\n getAnalyserNode(): AnalyserNode | null {\n return this.analyserNode;\n }\n\n /**\n * 设置状态\n * Set state\n */\n private setState(state: AudioInputState): void {\n this.state = state;\n }\n\n /**\n * 检查是否正在运行\n * Check if running\n */\n isRunning(): boolean {\n return this.state === 'active';\n }\n}\n\n","/**\n * 音高检测器\n * Pitch Detector\n * \n * 使用自相关算法检测音频中的音高\n * Uses autocorrelation algorithm to detect pitch in audio\n */\n\nimport type { NoteInfo } from '../types';\n\nexport class PitchDetector {\n private sampleRate: number;\n private minFrequency: number;\n private maxFrequency: number;\n\n // 音符名称映射\n private static readonly NOTE_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n\n constructor(sampleRate: number = 44100, minFrequency: number = 27.5, maxFrequency: number = 4186) {\n this.sampleRate = sampleRate;\n this.minFrequency = minFrequency;\n this.maxFrequency = maxFrequency;\n }\n\n /**\n * 检测音高\n * Detect pitch using autocorrelation\n */\n detectPitch(audioBuffer: Float32Array, minVolume: number = 0.01): number | null {\n // 计算RMS音量\n const volume = this.calculateRMS(audioBuffer);\n if (volume < minVolume) {\n return null; // 音量太小,不检测\n }\n\n // 使用自相关算法检测音高\n const frequency = this.autoCorrelate(audioBuffer);\n \n if (frequency === -1 || frequency < this.minFrequency || frequency > this.maxFrequency) {\n return null;\n }\n\n return frequency;\n }\n\n /**\n * 自相关算法\n * Autocorrelation algorithm\n */\n private autoCorrelate(buffer: Float32Array): number {\n const SIZE = buffer.length;\n const MAX_SAMPLES = Math.floor(SIZE / 2);\n let best_offset = -1;\n let best_correlation = 0;\n let rms = 0;\n\n // 计算RMS\n for (let i = 0; i < SIZE; i++) {\n const val = buffer[i];\n if (val !== undefined) {\n rms += val * val;\n }\n }\n rms = Math.sqrt(rms / SIZE);\n\n // 音量太小,不是音符\n if (rms < 0.01) {\n return -1;\n }\n\n // 找到第一个过零点\n let lastCorrelation = 1;\n for (let offset = 0; offset < MAX_SAMPLES; offset++) {\n let correlation = 0;\n\n for (let i = 0; i < MAX_SAMPLES; i++) {\n const val1 = buffer[i];\n const val2 = buffer[i + offset];\n if (val1 !== undefined && val2 !== undefined) {\n correlation += Math.abs(val1 - val2);\n }\n }\n\n correlation = 1 - correlation / MAX_SAMPLES;\n\n if (correlation > 0.9 && correlation > lastCorrelation) {\n const foundGoodCorrelation = correlation > best_correlation;\n if (foundGoodCorrelation) {\n best_correlation = correlation;\n best_offset = offset;\n }\n }\n\n lastCorrelation = correlation;\n }\n\n if (best_correlation > 0.01 && best_offset !== -1) {\n // 使用抛物线插值改进频率估计\n const frequency = this.sampleRate / best_offset;\n return frequency;\n }\n\n return -1;\n }\n\n /**\n * 计算RMS音量\n * Calculate RMS volume\n */\n private calculateRMS(buffer: Float32Array): number {\n let sum = 0;\n for (let i = 0; i < buffer.length; i++) {\n const val = buffer[i];\n if (val !== undefined) {\n sum += val * val;\n }\n }\n return Math.sqrt(sum / buffer.length);\n }\n\n /**\n * 将频率转换为音符信息\n * Convert frequency to note information\n */\n frequencyToNote(frequency: number, volume: number = 1): NoteInfo | null {\n if (frequency <= 0) {\n return null;\n }\n\n // 计算MIDI音符编号\n const midi = Math.round(12 * Math.log2(frequency / 440) + 69);\n \n if (midi < 0 || midi > 127) {\n return null;\n }\n\n // 计算音符名称和八度\n const noteIndex = midi % 12;\n const octave = Math.floor(midi / 12) - 1;\n const noteName = PitchDetector.NOTE_NAMES[noteIndex] || 'C';\n const name = `${noteName}${octave}`;\n\n // 计算标准频率(用于计算置信度)\n const standardFrequency = 440 * Math.pow(2, (midi - 69) / 12);\n const cents = 1200 * Math.log2(frequency / standardFrequency);\n const confidence = Math.max(0, 1 - Math.abs(cents) / 50); // 50音分容差\n\n return {\n name,\n frequency,\n noteName,\n octave,\n midi,\n volume,\n confidence,\n };\n }\n\n /**\n * 使用FFT检测主频率\n * Detect dominant frequency using FFT\n */\n detectDominantFrequency(frequencyData: Float32Array, minVolume: number = -60): number | null {\n const nyquist = this.sampleRate / 2;\n const binWidth = nyquist / frequencyData.length;\n \n let maxIndex = -1;\n let maxValue = -Infinity;\n\n // 只在我们关心的频率范围内搜索\n const minBin = Math.floor(this.minFrequency / binWidth);\n const maxBin = Math.ceil(this.maxFrequency / binWidth);\n\n for (let i = minBin; i < Math.min(maxBin, frequencyData.length); i++) {\n const value = frequencyData[i];\n if (value !== undefined && value > maxValue && value > minVolume) {\n maxValue = value;\n maxIndex = i;\n }\n }\n\n if (maxIndex === -1) {\n return null;\n }\n\n // 使用抛物线插值改进频率估计\n const frequency = this.parabolicInterpolation(frequencyData, maxIndex, binWidth);\n \n return frequency;\n }\n\n /**\n * 抛物线插值\n * Parabolic interpolation for better frequency estimation\n */\n private parabolicInterpolation(data: Float32Array, index: number, binWidth: number): number {\n if (index <= 0 || index >= data.length - 1) {\n return index * binWidth;\n }\n\n const y1 = data[index - 1];\n const y2 = data[index];\n const y3 = data[index + 1];\n\n if (y1 === undefined || y2 === undefined || y3 === undefined) {\n return index * binWidth;\n }\n\n const delta = 0.5 * (y3 - y1) / (2 * y2 - y1 - y3);\n const interpolatedIndex = index + delta;\n\n return interpolatedIndex * binWidth;\n }\n\n /**\n * 检测多个音高(和弦)\n * Detect multiple pitches (chords)\n */\n detectMultiplePitches(frequencyData: Float32Array, minVolume: number = -60): NoteInfo[] {\n const notes: NoteInfo[] = [];\n const nyquist = this.sampleRate / 2;\n const binWidth = nyquist / frequencyData.length;\n \n // 找到所有峰值\n const peaks: { index: number; value: number }[] = [];\n \n for (let i = 1; i < frequencyData.length - 1; i++) {\n const freq = i * binWidth;\n if (freq < this.minFrequency || freq > this.maxFrequency) {\n continue;\n }\n\n const value = frequencyData[i];\n if (value !== undefined && value > minVolume && \n value > (frequencyData[i - 1] ?? -Infinity) && \n value > (frequencyData[i + 1] ?? -Infinity)) {\n peaks.push({ index: i, value });\n }\n }\n\n // 按强度排序,取前5个\n peaks.sort((a, b) => b.value - a.value);\n const topPeaks = peaks.slice(0, 5);\n\n // 转换为音符\n for (const peak of topPeaks) {\n const frequency = this.parabolicInterpolation(frequencyData, peak.index, binWidth);\n \n // 计算相对音量(归一化到0-1)\n const volume = Math.pow(10, peak.value / 20); // 从dB转换\n \n const note = this.frequencyToNote(frequency, volume);\n if (note) {\n notes.push(note);\n }\n }\n\n return notes;\n }\n}\n\n","/**\n * 和弦识别器\n * Chord Recognizer\n * \n * 根据检测到的音符识别和弦\n * Recognizes chords based on detected notes\n */\n\nimport type { NoteInfo, ChordInfo } from '../types';\n\ninterface ChordPattern {\n name: string;\n intervals: number[]; // 相对于根音的半音数\n aliases?: string[];\n}\n\nexport class ChordRecognizer {\n // 和弦模式定义\n private static readonly CHORD_PATTERNS: ChordPattern[] = [\n // 三和弦\n { name: 'major', intervals: [0, 4, 7], aliases: ['maj', 'M'] },\n { name: 'minor', intervals: [0, 3, 7], aliases: ['min', 'm'] },\n { name: 'diminished', intervals: [0, 3, 6], aliases: ['dim', '°'] },\n { name: 'augmented', intervals: [0, 4, 8], aliases: ['aug', '+'] },\n { name: 'sus2', intervals: [0, 2, 7] },\n { name: 'sus4', intervals: [0, 5, 7] },\n \n // 七和弦\n { name: 'major7', intervals: [0, 4, 7, 11], aliases: ['maj7', 'M7'] },\n { name: 'minor7', intervals: [0, 3, 7, 10], aliases: ['min7', 'm7'] },\n { name: 'dominant7', intervals: [0, 4, 7, 10], aliases: ['7'] },\n { name: 'diminished7', intervals: [0, 3, 6, 9], aliases: ['dim7', '°7'] },\n { name: 'half-diminished7', intervals: [0, 3, 6, 10], aliases: ['m7b5', 'ø7'] },\n { name: 'minor-major7', intervals: [0, 3, 7, 11], aliases: ['mM7', 'm(maj7)'] },\n { name: 'augmented7', intervals: [0, 4, 8, 10], aliases: ['aug7', '+7'] },\n \n // 扩展和弦\n { name: 'major9', intervals: [0, 4, 7, 11, 14], aliases: ['maj9', 'M9'] },\n { name: 'minor9', intervals: [0, 3, 7, 10, 14], aliases: ['min9', 'm9'] },\n { name: 'dominant9', intervals: [0, 4, 7, 10, 14], aliases: ['9'] },\n { name: 'add9', intervals: [0, 4, 7, 14] },\n { name: 'madd9', intervals: [0, 3, 7, 14], aliases: ['m(add9)'] },\n ];\n\n private static readonly NOTE_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n\n /**\n * 识别和弦\n * Recognize chord from notes\n */\n recognizeChord(notes: NoteInfo[]): ChordInfo | null {\n if (notes.length < 2) {\n return null; // 至少需要2个音符才能构成和弦\n }\n\n // 按音高排序\n const sortedNotes = [...notes].sort((a, b) => a.midi - b.midi);\n\n // 去重(相同音符的不同八度)\n const uniqueNoteClasses = this.getUniqueNoteClasses(sortedNotes);\n \n if (uniqueNoteClasses.length < 2) {\n return null;\n }\n\n // 尝试所有可能的根音\n let bestMatch: { root: string; pattern: ChordPattern; confidence: number } | null = null;\n\n for (let i = 0; i < uniqueNoteClasses.length; i++) {\n const root = uniqueNoteClasses[i];\n if (!root) continue; // 跳过 undefined\n \n const intervals = this.calculateIntervals(root, uniqueNoteClasses);\n \n // 匹配和弦模式\n for (const pattern of ChordRecognizer.CHORD_PATTERNS) {\n const confidence = this.matchPattern(intervals, pattern.intervals);\n \n if (confidence > 0.8 && (!bestMatch || confidence > bestMatch.confidence)) {\n bestMatch = { root, pattern, confidence };\n }\n }\n }\n\n if (!bestMatch) {\n return null;\n }\n\n // 构建和弦信息\n const chordName = `${bestMatch.root}${this.getChordSuffix(bestMatch.pattern)}`;\n \n return {\n name: chordName,\n root: bestMatch.root,\n type: bestMatch.pattern.name,\n notes: sortedNotes,\n confidence: bestMatch.confidence,\n };\n }\n\n /**\n * 获取唯一的音符类别(不考虑八度)\n * Get unique note classes (ignoring octave)\n */\n private getUniqueNoteClasses(notes: NoteInfo[]): string[] {\n const noteSet = new Set<string>();\n for (const note of notes) {\n noteSet.add(note.noteName);\n }\n return Array.from(noteSet);\n }\n\n /**\n * 计算音程\n * Calculate intervals from root\n */\n private calculateIntervals(root: string, noteClasses: string[]): number[] {\n const rootIndex = ChordRecognizer.NOTE_NAMES.indexOf(root);\n const intervals: number[] = [];\n\n for (const noteClass of noteClasses) {\n const noteIndex = ChordRecognizer.NOTE_NAMES.indexOf(noteClass);\n let interval = (noteIndex - rootIndex + 12) % 12;\n intervals.push(interval);\n }\n\n return intervals.sort((a, b) => a - b);\n }\n\n /**\n * 匹配和弦模式\n * Match chord pattern\n */\n private matchPattern(intervals: number[], pattern: number[]): number {\n if (intervals.length < pattern.length) {\n return 0;\n }\n\n let matches = 0;\n for (const patternInterval of pattern) {\n if (intervals.includes(patternInterval)) {\n matches++;\n }\n }\n\n // 计算匹配度\n const precision = matches / pattern.length;\n const recall = matches / intervals.length;\n \n // 使用F1分数\n if (precision + recall === 0) {\n return 0;\n }\n \n return (2 * precision * recall) / (precision + recall);\n }\n\n /**\n * 获取和弦后缀\n * Get chord suffix for display\n */\n private getChordSuffix(pattern: ChordPattern): string {\n // 使用最短的别名或原名称\n if (pattern.aliases && pattern.aliases.length > 0) {\n return pattern.aliases[0] || '';\n }\n \n // 转换常见名称\n const suffixMap: { [key: string]: string } = {\n 'major': '',\n 'minor': 'm',\n 'diminished': 'dim',\n 'augmented': 'aug',\n 'dominant7': '7',\n };\n \n return suffixMap[pattern.name] ?? pattern.name;\n }\n\n /**\n * 识别八度内的音程(用于简单的音程识别)\n * Recognize interval within an octave\n */\n recognizeInterval(note1: NoteInfo, note2: NoteInfo): string {\n const semitones = Math.abs(note1.midi - note2.midi) % 12;\n \n const intervalNames: { [key: number]: string } = {\n 0: '纯一度 (Unison)',\n 1: '小二度 (Minor 2nd)',\n 2: '大二度 (Major 2nd)',\n 3: '小三度 (Minor 3rd)',\n 4: '大三度 (Major 3rd)',\n 5: '纯四度 (Perfect 4th)',\n 6: '增四度/减五度 (Tritone)',\n 7: '纯五度 (Perfect 5th)',\n 8: '小六度 (Minor 6th)',\n 9: '大六度 (Major 6th)',\n 10: '小七度 (Minor 7th)',\n 11: '大七度 (Major 7th)',\n };\n \n return intervalNames[semitones] || '未知音程';\n }\n\n /**\n * 分析和弦质量\n * Analyze chord quality\n */\n analyzeChordQuality(chord: ChordInfo): string {\n const qualities: string[] = [];\n \n if (chord.type.includes('major')) {\n qualities.push('大调');\n } else if (chord.type.includes('minor')) {\n qualities.push('小调');\n }\n \n if (chord.type.includes('diminished')) {\n qualities.push('减');\n } else if (chord.type.includes('augmented')) {\n qualities.push('增');\n }\n \n if (chord.type.includes('7')) {\n qualities.push('七和弦');\n } else if (chord.type.includes('9')) {\n qualities.push('九和弦');\n }\n \n if (chord.type.includes('sus')) {\n qualities.push('挂留');\n }\n \n return qualities.join(' ') || '基础和弦';\n }\n}\n\n","/**\n * 音频检测器 - 主控制器\n * Audio Detector - Main Controller\n * \n * 整合音频输入、音高检测和和弦识别\n * Integrates audio input, pitch detection, and chord recognition\n */\n\nimport { AudioInputService } from './AudioInputService';\nimport { PitchDetector } from './PitchDetector';\nimport { ChordRecognizer } from './ChordRecognizer';\nimport type { \n AudioInputConfig, \n AudioDetectionResult, \n AudioDetectorEvents,\n AudioInputState,\n NoteInfo,\n ChordInfo,\n} from '../types';\n\nexport class AudioDetector {\n private audioInput: AudioInputService;\n private pitchDetector: PitchDetector;\n private chordRecognizer: ChordRecognizer;\n private isDetecting: boolean = false;\n private animationFrameId: number | null = null;\n private events: AudioDetectorEvents;\n private lastResult: AudioDetectionResult | null = null;\n\n constructor(config: AudioInputConfig = {}, events: AudioDetectorEvents = {}) {\n this.audioInput = new AudioInputService(config);\n const audioConfig = this.audioInput.getConfig();\n \n this.pitchDetector = new PitchDetector(\n audioConfig.sampleRate,\n audioConfig.frequencyRange.min,\n audioConfig.frequencyRange.max\n );\n \n this.chordRecognizer = new ChordRecognizer();\n this.events = events;\n }\n\n /**\n * 启动音频检测\n * Start audio detection\n */\n async start(): Promise<void> {\n if (this.isDetecting) {\n console.warn('AudioDetector 已经在运行');\n return;\n }\n\n try {\n // 初始化音频输入\n await this.audioInput.initialize();\n \n // 通知状态变化\n this.events.onStateChange?.('active');\n \n // 开始检测循环\n this.isDetecting = true;\n this.detectLoop();\n \n console.log('AudioDetector 已启动');\n } catch (error) {\n this.events.onStateChange?.('error');\n this.events.onError?.(error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n\n /**\n * 停止音频检测\n * Stop audio detection\n */\n stop(): void {\n if (!this.isDetecting) {\n return;\n }\n\n this.isDetecting = false;\n \n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n\n this.audioInput.stop();\n this.events.onStateChange?.('stopped');\n \n console.log('AudioDetector 已停止');\n }\n\n /**\n * 检测循环\n * Detection loop\n */\n private detectLoop = (): void => {\n if (!this.isDetecting) {\n return;\n }\n\n try {\n const result = this.detect();\n \n if (result) {\n this.lastResult = result;\n this.events.onDetection?.(result);\n }\n } catch (error) {\n console.error('检测过程中出错:', error);\n this.events.onError?.(error instanceof Error ? error : new Error(String(error)));\n }\n\n // 继续下一帧\n this.animationFrameId = requestAnimationFrame(this.detectLoop);\n };\n\n /**\n * 执行一次检测\n * Perform single detection\n */\n private detect(): AudioDetectionResult | null {\n const config = this.audioInput.getConfig();\n\n // 获取时域数据(用于自相关)\n const timeDomainData = this.audioInput.getTimeDomainData();\n \n // 获取频域数据(用于多音检测)\n const frequencyData = this.audioInput.getFrequencyData();\n \n // 获取当前音量\n const volume = this.audioInput.getCurrentVolume();\n\n // 调试日志:每2秒输出一次音量信息\n if (Date.now() % 2000 < 100) {\n console.log(`[AudioDetector] 当前音量: ${volume.toFixed(6)}, 阈值: ${config.minVolume}, 状态: ${volume >= config.minVolume ? '✅ 有声音' : '❌ 音量太低'}`);\n }\n\n // 检查是否有足够的音量\n if (volume < config.minVolume) {\n return {\n notes: [],\n timestamp: Date.now(),\n isDetecting: false,\n };\n }\n\n // 方法1: 使用时域自相关检测主音高\n const dominantFrequency = this.pitchDetector.detectPitch(timeDomainData, config.minVolume);\n \n // 方法2: 使用频域检测多个音高\n const detectedNotes = this.pitchDetector.detectMultiplePitches(frequencyData, -60);\n \n // 如果时域检测到了主音高,确保它在结果中\n if (dominantFrequency && dominantFrequency > 0) {\n const dominantNote = this.pitchDetector.frequencyToNote(dominantFrequency, volume);\n if (dominantNote) {\n // 检查是否已经在列表中\n const exists = detectedNotes.some(n => Math.abs(n.midi - dominantNote.midi) < 1);\n if (!exists) {\n detectedNotes.unshift(dominantNote);\n }\n }\n }\n\n // 过滤掉置信度太低的音符\n const filteredNotes = detectedNotes.filter(note => note.confidence >= config.minConfidence);\n\n // 识别和弦\n let chord: ChordInfo | undefined;\n if (filteredNotes.length >= 2) {\n chord = this.chordRecognizer.recognizeChord(filteredNotes) ?? undefined;\n }\n\n return {\n notes: filteredNotes,\n chord,\n timestamp: Date.now(),\n isDetecting: filteredNotes.length > 0,\n };\n }\n\n /**\n * 获取当前状态\n * Get current state\n */\n getState(): AudioInputState {\n return this.audioInput.getState();\n }\n\n /**\n * 获取最后的检测结果\n * Get last detection result\n */\n getLastResult(): AudioDetectionResult | null {\n return this.lastResult;\n }\n\n /**\n * 检查是否正在运行\n * Check if running\n */\n isRunning(): boolean {\n return this.isDetecting && this.audioInput.isRunning();\n }\n\n /**\n * 获取音频输入服务\n * Get audio input service\n */\n getAudioInput(): AudioInputService {\n return this.audioInput;\n }\n}\n\n","/**\n * 音频检测调试工具\n * Audio Detection Debug Tool\n */\n\nimport { AudioDetector } from './AudioDetector';\nimport type { AudioInputConfig } from '../types';\n\nexport class AudioDetectorDebugger {\n private detector: AudioDetector;\n private debugInterval: number | null = null;\n\n constructor(config: AudioInputConfig = {}) {\n this.detector = new AudioDetector(config, {\n onDetection: (result) => {\n if (result.isDetecting) {\n console.log('🎵 检测到音符:', result.notes.map(n => `${n.name}(${n.frequency.toFixed(1)}Hz)`).join(', '));\n if (result.chord) {\n console.log('🎹 检测到和弦:', result.chord.name);\n }\n }\n },\n onStateChange: (state) => {\n console.log('📊 状态变化:', state);\n },\n onError: (error) => {\n console.error('❌ 错误:', error);\n },\n });\n }\n\n async start(): Promise<void> {\n await this.detector.start();\n \n // 启动调试信息输出\n this.debugInterval = window.setInterval(() => {\n const audioInput = this.detector.getAudioInput();\n const volume = audioInput.getCurrentVolume();\n const config = audioInput.getConfig();\n const analyser = audioInput.getAnalyserNode();\n \n if (analyser) {\n // 获取频域数据\n const freqData = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(freqData);\n \n // 找到最大值\n let maxFreqValue = -Infinity;\n for (let i = 0; i < freqData.length; i++) {\n const val = freqData[i];\n if (val !== undefined && val > maxFreqValue) {\n maxFreqValue = val;\n }\n }\n \n console.log(`\n🎤 音频调试信息:\n - 音量 (RMS): ${volume.toFixed(6)}\n - 音量阈值: ${config.minVolume}\n - 音量状态: ${volume >= config.minVolume ? '✅ 超过阈值' : '❌ 低于阈值'}\n - 最大频率强度: ${maxFreqValue.toFixed(2)} dB\n - 采样率: ${config.sampleRate} Hz\n - FFT大小: ${config.fftSize}\n - 平滑系数: ${config.smoothing}\n `);\n }\n }, 2000);\n }\n\n stop(): void {\n if (this.debugInterval !== null) {\n clearInterval(this.debugInterval);\n this.debugInterval = null;\n }\n this.detector.stop();\n }\n\n getDetector(): AudioDetector {\n return this.detector;\n }\n\n /**\n * 测试麦克风是否正常工作\n */\n async testMicrophone(): Promise<{\n hasPermission: boolean;\n isReceivingAudio: boolean;\n averageVolume: number;\n peakVolume: number;\n }> {\n console.log('🔍 开始测试麦克风...');\n \n await this.detector.start();\n \n // 收集5秒的音量数据\n const volumes: number[] = [];\n const audioInput = this.detector.getAudioInput();\n \n return new Promise((resolve) => {\n const sampleInterval = setInterval(() => {\n volumes.push(audioInput.getCurrentVolume());\n }, 100);\n \n setTimeout(() => {\n clearInterval(sampleInterval);\n \n const averageVolume = volumes.reduce((a, b) => a + b, 0) / volumes.length;\n const peakVolume = Math.max(...volumes);\n const isReceivingAudio = peakVolume > 0.0001;\n \n console.log(`\n✅ 麦克风测试完成:\n - 权限状态: ✅ 已授权\n - 接收音频: ${isReceivingAudio ? '✅ 是' : '❌ 否'}\n - 平均音量: ${averageVolume.toFixed(6)}\n - 峰值音量: ${peakVolume.toFixed(6)}\n - 建议阈值: ${(peakVolume * 0.1).toFixed(6)}\n `);\n \n resolve({\n hasPermission: true,\n isReceivingAudio,\n averageVolume,\n peakVolume,\n });\n }, 5000);\n });\n }\n}\n\n// 导出便捷函数\nexport async function debugAudioDetection(config?: AudioInputConfig): Promise<AudioDetectorDebugger> {\n const dbg = new AudioDetectorDebugger(config);\n await dbg.start();\n return dbg;\n}\n\nexport async function testMicrophone(): Promise<void> {\n const dbg = new AudioDetectorDebugger();\n await dbg.testMicrophone();\n dbg.stop();\n}\n\n","/**\n * 音频检测 React Hook\n * Audio Detection React Hook\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { AudioDetector } from '../core/AudioDetector';\nimport type { \n AudioInputConfig, \n AudioDetectionResult, \n AudioInputState,\n} from '../types';\n\nexport interface UseAudioDetectionOptions extends AudioInputConfig {\n /** 是否自动开始检测 */\n autoStart?: boolean;\n /** 检测结果更新间隔(毫秒) */\n updateInterval?: number;\n}\n\nexport interface UseAudioDetectionReturn {\n /** 当前检测结果 */\n result: AudioDetectionResult | null;\n /** 音频输入状态 */\n state: AudioInputState;\n /** 是否正在检测 */\n isDetecting: boolean;\n /** 错误信息 */\n error: Error | null;\n /** 启动检测 */\n start: () => Promise<void>;\n /** 停止检测 */\n stop: () => void;\n /** 获取检测器实例 */\n getDetector: () => AudioDetector | null;\n}\n\n/**\n * 使用音频检测的 Hook\n * Hook for using audio detection\n */\nexport function useAudioDetection(options: UseAudioDetectionOptions = {}): UseAudioDetectionReturn {\n const { autoStart = false, updateInterval = 100, ...config } = options;\n \n const [result, setResult] = useState<AudioDetectionResult | null>(null);\n const [state, setState] = useState<AudioInputState>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [isDetecting, setIsDetecting] = useState(false);\n \n const detectorRef = useRef<AudioDetector | null>(null);\n const lastUpdateRef = useRef<number>(0);\n\n // 初始化检测器\n useEffect(() => {\n const detector = new AudioDetector(config, {\n onDetection: (detectionResult) => {\n // 限制更新频率\n const now = Date.now();\n if (now - lastUpdateRef.current >= updateInterval) {\n setResult(detectionResult);\n lastUpdateRef.current = now;\n }\n },\n onStateChange: (newState) => {\n setState(newState);\n },\n onError: (err) => {\n setError(err);\n setIsDetecting(false);\n },\n });\n\n detectorRef.current = detector;\n\n // 自动启动\n if (autoStart) {\n detector.start().catch((err) => {\n setError(err);\n });\n setIsDetecting(true);\n }\n\n // 清理\n return () => {\n if (detector.isRunning()) {\n detector.stop();\n }\n };\n }, []); // 只在挂载时初始化\n\n // 启动检测\n const start = useCallback(async () => {\n if (!detectorRef.current) {\n const err = new Error('检测器未初始化');\n setError(err);\n throw err;\n }\n\n try {\n setError(null);\n await detectorRef.current.start();\n setIsDetecting(true);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setIsDetecting(false);\n throw error;\n }\n }, []);\n\n // 停止检测\n const stop = useCallback(() => {\n if (detectorRef.current) {\n detectorRef.current.stop();\n setIsDetecting(false);\n setResult(null);\n }\n }, []);\n\n // 获取检测器实例\n const getDetector = useCallback(() => {\n return detectorRef.current;\n }, []);\n\n return {\n result,\n state,\n isDetecting,\n error,\n start,\n stop,\n getDetector,\n };\n}\n\n","/**\n * 音频检测组件\n * Audio Detection Component\n * \n * 显示实时音频检测结果的React组件\n * React component for displaying real-time audio detection results\n */\n\nimport React from 'react';\nimport { useAudioDetection, type UseAudioDetectionOptions } from '../hooks/useAudioDetection';\nimport type { NoteInfo, ChordInfo } from '../types';\n\nexport interface AudioDetectionDisplayProps extends UseAudioDetectionOptions {\n /** 自定义类名 */\n className?: string;\n /** 是否显示调试信息 */\n showDebugInfo?: boolean;\n /** 自定义渲染音符 */\n renderNote?: (note: NoteInfo) => React.ReactNode;\n /** 自定义渲染和弦 */\n renderChord?: (chord: ChordInfo) => React.ReactNode;\n /** 开始按钮文本 */\n startButtonText?: string;\n /** 停止按钮文本 */\n stopButtonText?: string;\n}\n\n/**\n * 音频检测显示组件\n */\nexport const AudioDetectionDisplay: React.FC<AudioDetectionDisplayProps> = ({\n className = '',\n showDebugInfo = false,\n renderNote,\n renderChord,\n startButtonText = '开始检测',\n stopButtonText = '停止检测',\n ...options\n}) => {\n const { result, state, isDetecting, error, start, stop } = useAudioDetection(options);\n\n const handleToggle = async () => {\n if (isDetecting) {\n stop();\n } else {\n try {\n await start();\n } catch (err) {\n console.error('启动失败:', err);\n }\n }\n };\n\n return (\n <div className={`audio-detection-display ${className}`}>\n {/* 控制按钮 */}\n <div className=\"audio-detection-controls\">\n <button\n onClick={handleToggle}\n disabled={state === 'initializing'}\n className={`audio-detection-button ${isDetecting ? 'active' : ''}`}\n >\n {state === 'initializing' ? '初始化中...' : isDetecting ? stopButtonText : startButtonText}\n </button>\n \n <div className={`audio-detection-status status-${state}`}>\n 状态: {getStateLabel(state)}\n </div>\n </div>\n\n {/* 错误信息 */}\n {error && (\n <div className=\"audio-detection-error\">\n <strong>错误:</strong> {error.message}\n </div>\n )}\n\n {/* 检测结果 */}\n {result && result.isDetecting && (\n <div className=\"audio-detection-result\">\n {/* 音符显示 */}\n {result.notes.length > 0 && (\n <div className=\"audio-detection-notes\">\n <h3>检测到的音符:</h3>\n <div className=\"notes-grid\">\n {result.notes.map((note, index) => (\n <div key={index} className=\"note-item\">\n {renderNote ? renderNote(note) : <DefaultNoteDisplay note={note} />}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* 和弦显示 */}\n {result.chord && (\n <div className=\"audio-detection-chord\">\n <h3>识别的和弦:</h3>\n {renderChord ? renderChord(result.chord) : <DefaultChordDisplay chord={result.chord} />}\n </div>\n )}\n\n {/* 调试信息 */}\n {showDebugInfo && (\n <div className=\"audio-detection-debug\">\n <h4>调试信息:</h4>\n <pre>{JSON.stringify(result, null, 2)}</pre>\n </div>\n )}\n </div>\n )}\n\n {/* 无检测结果时的提示 */}\n {isDetecting && (!result || !result.isDetecting) && (\n <div className=\"audio-detection-waiting\">\n 正在监听... 请弹奏电子琴\n </div>\n )}\n </div>\n );\n};\n\n/**\n * 默认音符显示\n */\nconst DefaultNoteDisplay: React.FC<{ note: NoteInfo }> = ({ note }) => (\n <div className=\"default-note-display\">\n <div className=\"note-name\">{note.name}</div>\n <div className=\"note-frequency\">{note.frequency.toFixed(2)} Hz</div>\n <div className=\"note-confidence\">\n 置信度: {(note.confidence * 100).toFixed(0)}%\n </div>\n </div>\n);\n\n/**\n * 默认和弦显示\n */\nconst DefaultChordDisplay: React.FC<{ chord: ChordInfo }> = ({ chord }) => (\n <div className=\"default-chord-display\">\n <div className=\"chord-name\">{chord.name}</div>\n <div className=\"chord-type\">类型: {chord.type}</div>\n <div className=\"chord-notes\">\n 音符: {chord.notes.map(n => n.name).join(', ')}\n </div>\n <div className=\"chord-confidence\">\n 置信度: {(chord.confidence * 100).toFixed(0)}%\n </div>\n </div>\n);\n\n/**\n * 获取状态标签\n */\nfunction getStateLabel(state: string): string {\n const labels: { [key: string]: string } = {\n idle: '空闲',\n initializing: '初始化中',\n active: '运行中',\n error: '错误',\n stopped: '已停止',\n };\n return labels[state] || state;\n}\n\n/**\n * 默认样式(可以通过CSS覆盖)\n */\nexport const audioDetectionStyles = `\n.audio-detection-display {\n padding: 20px;\n border: 1px solid #ddd;\n border-radius: 8px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.audio-detection-controls {\n display: flex;\n gap: 12px;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.audio-detection-button {\n padding: 10px 20px;\n font-size: 16px;\n border: none;\n border-radius: 6px;\n background-color: #007bff;\n color: white;\n cursor: pointer;\n transition: background-color 0.3s;\n}\n\n.audio-detection-button:hover {\n background-color: #0056b3;\n}\n\n.audio-detection-button:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.audio-detection-button.active {\n background-color: #dc3545;\n}\n\n.audio-detection-button.active:hover {\n background-color: #c82333;\n}\n\n.audio-detection-status {\n padding: 8px 16px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.status-idle { background-color: #e7f3ff; color: #004085; }\n.status-initializing { background-color: #fff3cd; color: #856404; }\n.status-active { background-color: #d4edda; color: #155724; }\n.status-error { background-color: #f8d7da; color: #721c24; }\n.status-stopped { background-color: #e2e3e5; color: #383d41; }\n\n.audio-detection-error {\n padding: 12px;\n background-color: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 4px;\n color: #721c24;\n margin-bottom: 16px;\n}\n\n.audio-detection-result {\n margin-top: 20px;\n}\n\n.audio-detection-notes h3,\n.audio-detection-chord h3 {\n margin-bottom: 12px;\n font-size: 18px;\n}\n\n.notes-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n}\n\n.note-item {\n padding: 12px;\n border: 2px solid #007bff;\n border-radius: 6px;\n background-color: #f8f9fa;\n}\n\n.default-note-display {\n text-align: center;\n}\n\n.note-name {\n font-size: 24px;\n font-weight: bold;\n color: #007bff;\n margin-bottom: 4px;\n}\n\n.note-frequency {\n font-size: 14px;\n color: #666;\n margin-bottom: 4px;\n}\n\n.note-confidence {\n font-size: 12px;\n color: #999;\n}\n\n.audio-detection-chord {\n margin-top: 20px;\n padding: 16px;\n border: 2px solid #28a745;\n border-radius: 8px;\n background-color: #f8f9fa;\n}\n\n.default-chord-display {\n text-align: center;\n}\n\n.chord-name {\n font-size: 32px;\n font-weight: bold;\n color: #28a745;\n margin-bottom: 8px;\n}\n\n.chord-type,\n.chord-notes,\n.chord-confidence {\n margin-bottom: 4px;\n color: #666;\n}\n\n.audio-detection-waiting {\n text-align: center;\n padding: 40px;\n color: #666;\n font-size: 18px;\n}\n\n.audio-detection-debug {\n margin-top: 20px;\n padding: 12px;\n background-color: #f4f4f4;\n border-radius: 4px;\n}\n\n.audio-detection-debug pre {\n margin: 8px 0 0 0;\n font-size: 12px;\n overflow-x: auto;\n}\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","/**\n * 钢琴键盘可视化组件\n * Piano Keyboard Visualization Component\n */\n\nimport React, { useMemo } from 'react';\nimport type { NoteInfo } from '../types';\n\nexport interface PianoKeyboardProps {\n /** 当前激活的音符 */\n activeNotes?: NoteInfo[];\n /** 起始八度 (默认: 2) */\n startOctave?: number;\n /** 结束八度 (默认: 6) */\n endOctave?: number;\n /** 自定义类名 */\n className?: string;\n /** 是否显示音符名称 */\n showNoteNames?: boolean;\n}\n\ninterface PianoKey {\n noteName: string;\n octave: number;\n midi: number;\n isBlack: boolean;\n isActive: boolean;\n}\n\n/**\n * 钢琴键盘可视化\n */\nexport const PianoKeyboard: React.FC<PianoKeyboardProps> = ({\n activeNotes = [],\n startOctave = 2,\n endOctave = 6,\n className = '',\n showNoteNames = true,\n}) => {\n // 生成钢琴键\n const keys = useMemo(() => {\n const noteNames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n const blackKeys = new Set(['C#', 'D#', 'F#', 'G#', 'A#']);\n const allKeys: PianoKey[] = [];\n\n for (let octave = startOctave; octave <= endOctave; octave++) {\n for (const noteName of noteNames) {\n const midi = (octave + 1) * 12 + noteNames.indexOf(noteName);\n const isActive = activeNotes.some(note => note.midi === midi);\n \n allKeys.push({\n noteName,\n octave,\n midi,\n isBlack: blackKeys.has(noteName),\n isActive,\n });\n }\n }\n\n return allKeys;\n }, [startOctave, endOctave, activeNotes]);\n\n // 分离白键和黑键\n const whiteKeys = keys.filter(k => !k.isBlack);\n const blackKeys = keys.filter(k => k.isBlack);\n\n return (\n <div className={`piano-keyboard ${className}`}>\n <div className=\"piano-keys-container\">\n {/* 白键 */}\n <div className=\"white-keys\">\n {whiteKeys.map((key, index) => (\n <div\n key={`white-${key.midi}`}\n className={`piano-key white-key ${key.isActive ? 'active' : ''}`}\n title={`${key.noteName}${key.octave}`}\n >\n {showNoteNames && (\n <span className=\"key-label\">{key.noteName}{key.octave}</span>\n )}\n </div>\n ))}\n </div>\n\n {/* 黑键 */}\n <div className=\"black-keys\">\n {blackKeys.map((key) => {\n // 计算黑键的位置\n const whiteKeyIndex = getWhiteKeyIndexBeforeBlack(key.noteName);\n const octaveOffset = (key.octave - startOctave) * 7; // 每个八度有7个白键\n const position = whiteKeyIndex + octaveOffset;\n\n return (\n <div\n key={`black-${key.midi}`}\n className={`piano-key black-key ${key.isActive ? 'active' : ''}`}\n style={{ left: `${(position + 0.7) * (100 / whiteKeys.length)}%` }}\n title={`${key.noteName}${key.octave}`}\n >\n {showNoteNames && (\n <span className=\"key-label\">{key.noteName}{key.octave}</span>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * 获取黑键之前的白键索引\n */\nfunction getWhiteKeyIndexBeforeBlack(noteName: string): number {\n const map: { [key: string]: number } = {\n 'C#': 0,\n 'D#': 1,\n 'F#': 3,\n 'G#': 4,\n 'A#': 5,\n };\n return map[noteName] || 0;\n}\n\n/**\n * 钢琴键盘样式\n */\nexport const pianoKeyboardStyles = `\n.piano-keyboard {\n width: 100%;\n padding: 20px;\n background-color: #2c3e50;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n}\n\n.piano-keys-container {\n position: relative;\n width: 100%;\n height: 200px;\n}\n\n.white-keys {\n display: flex;\n height: 100%;\n gap: 2px;\n}\n\n.piano-key {\n position: relative;\n border: 1px solid #000;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.white-key {\n flex: 1;\n background: linear-gradient(to bottom, #ffffff 0%, #f0f0f0 100%);\n border-radius: 0 0 4px 4px;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 8px;\n}\n\n.white-key:hover {\n background: linear-gradient(to bottom, #f8f8f8 0%, #e8e8e8 100%);\n}\n\n.white-key.active {\n background: linear-gradient(to bottom, #4CAF50 0%, #45a049 100%) !important;\n box-shadow: 0 0 20px rgba(76, 175, 80, 0.8);\n}\n\n.black-keys {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 60%;\n pointer-events: none;\n}\n\n.black-key {\n position: absolute;\n width: calc(100% / 52 * 0.6); /* 假设有52个白键的宽度 */\n height: 100%;\n background: linear-gradient(to bottom, #2c3e50 0%, #1a252f 100%);\n border-radius: 0 0 3px 3px;\n pointer-events: all;\n transform: translateX(-50%);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 6px;\n z-index: 10;\n}\n\n.black-key:hover {\n background: linear-gradient(to bottom, #34495e 0%, #2c3e50 100%);\n}\n\n.black-key.active {\n background: linear-gradient(to bottom, #4CAF50 0%, #388E3C 100%) !important;\n box-shadow: 0 0 20px rgba(76, 175, 80, 0.8);\n}\n\n.key-label {\n font-size: 11px;\n font-weight: bold;\n user-select: none;\n}\n\n.white-key .key-label {\n color: #666;\n}\n\n.white-key.active .key-label {\n color: white;\n}\n\n.black-key .key-label {\n color: #ddd;\n}\n\n.black-key.active .key-label {\n color: white;\n}\n`;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"]}
|