Skip to content

Commit 5257ecb

Browse files
committed
init (third)
0 parents  commit 5257ecb

22 files changed

Lines changed: 3856 additions & 0 deletions

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Build directories
2+
/build
3+
/.vs
4+
/lib
5+
/.vscode
6+

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "lib/JUCE"]
2+
path = lib/JUCE
3+
url = https://github.com/juce-framework/JUCE

CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
cmake_minimum_required(VERSION 3.22)
2+
3+
project(juce_cmake_template VERSION 0.0.1)
4+
5+
enable_language(CXX)
6+
set(CMAKE_CXX_STANDARD 17)
7+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8+
set(CMAKE_CXX_EXTENSIONS OFF)
9+
10+
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
11+
add_compile_options(/utf-8)
12+
endif()
13+
14+
add_subdirectory(lib/JUCE)
15+
16+
juce_add_plugin(3HSPlug
17+
18+
COMPANY_NAME "src3453 @ KiTsuNeKo Works"
19+
COMPANY_COPYRIGHT "(C) 2025 src3453 licensed under AGPLv3"
20+
PLUGIN_MANUFACTURER_CODE KTNK
21+
PLUGIN_CODE 3HSP
22+
23+
FORMATS Standalone
24+
PRODUCT_NAME "3HSPlug")
25+
26+
juce_generate_juce_header(3HSPlug)
27+
28+
target_sources(3HSPlug
29+
PRIVATE
30+
src/PluginEditor.cpp
31+
src/PluginProcessor.cpp
32+
src/PatchBankData.cpp
33+
src/DrumKeymapManager.cpp
34+
src/DrumPcmSampleLoader.cpp
35+
)
36+
37+
target_compile_definitions(3HSPlug
38+
PUBLIC
39+
JUCE_WEB_BROWSER=0
40+
JUCE_USE_CURL=0
41+
JUCE_VST3_CAN_REPLACE_VST2=0)
42+
43+
target_link_libraries(3HSPlug
44+
PRIVATE
45+
juce::juce_audio_utils
46+
PUBLIC
47+
juce::juce_recommended_config_flags
48+
juce::juce_recommended_lto_flags
49+
juce::juce_recommended_warning_flags)

CMakePresets.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": 3,
3+
"cmakeMinimumRequired": {
4+
"major": 3,
5+
"minor": 22,
6+
"patch": 0
7+
},
8+
"configurePresets": [
9+
{
10+
"name": "vs2022",
11+
"displayName": "Visual Studio 17 2022",
12+
"generator": "Visual Studio 17 2022",
13+
"binaryDir": "${sourceDir}/build",
14+
"cacheVariables": {
15+
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
16+
}
17+
}
18+
]
19+
}

LICENSE

Lines changed: 661 additions & 0 deletions
Large diffs are not rendered by default.

s3hs register map.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
3HS88PWN4
2+
A core sound engine source code of 3HS88PWN4, a fantasy sound chip that written in C++. Also called S3HS for short, 3SGUC2 for internal Sound Generation Unit.
3+
4+
3HS88PWN4 Specifications:
5+
8-Channel 8-Operator Harmonic Synthesizer
6+
4-Channel PCM/Wavetable/Noise Synthesizer (With IIR Filter)
7+
16-bit 48KHz Stereo Linear PCM DAC
8+
3-band EQ (Low, Mid, High)
9+
Envelope Generator (ADSR)
10+
FM, RM, iPD, and combination synthesis modes
11+
8-bit PCM Sample Memory (4096 KBytes)
12+
Modulation with dynamic wavetable from PCM channel
13+
3HS88PWN4 I/O Map Allocations:
14+
0x000000 - 0x3FFFFF: PCM Sample Memory (4096 KBytes)
15+
0x400000 - 0x4003FF: Register Memory (512 Bytes)
16+
0x400400 - 0x403FFF: Unused
17+
18+
register maps:
19+
20+
|RAM Addr.| |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F| | |
21+
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
22+
|0x400000| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH1| |
23+
|0x400010| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
24+
|0x400020| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
25+
|0x400030| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
26+
|0x400040| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH2| |
27+
|0x400050| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
28+
|0x400060| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
29+
|0x400070| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
30+
|0x400080| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH3| |
31+
|0x400090| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
32+
|0x4000A0| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
33+
|0x4000B0| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
34+
|0x4000C0| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH4| |
35+
|0x4000D0| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
36+
|0x4000E0| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
37+
|0x4000F0| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
38+
|0x400100| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH5| |
39+
|0x400110| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
40+
|0x400120| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
41+
|0x400130| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
42+
|0x400140| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH6| |
43+
|0x400150| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
44+
|0x400160| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
45+
|0x400170| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
46+
|0x400180| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH7| |
47+
|0x400190| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
48+
|0x4001A0| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
49+
|0x4001B0| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
50+
|0x4001C0| |OP1 Freq| |OP2 Freq| |OP3 Freq | |OP4 Freq| |OP5 Freq| |OP6 Freq| |OP7 Freq| |OP8 Freq | |CH8| |
51+
|0x4001D0| |OP1V|OP2V|OP3V|OP4V|OP5V|OP6V|OP7V|OP8V|OP1W OP2W|OP3W OP4W|OP5W OP6W|OP7W OP8W|Mod Mode|L/R Vol|Gate|Mod FB| | |
52+
|0x4001E0| |OP1A|OP1D|OP1S|OP1R|OP2A|OP2D|OP2S|OP2R|OP3A|OP3D|OP3S|OP3R|OP4A|OP4D|OP4S|OP4R| | |
53+
|0x4001F0| |OP5A|OP5D|OP5S|OP5R|OP6A|OP6D|OP6S|OP6R|OP7A|OP7D|OP7S|OP7R|OP8A|OP8D|OP8S|OP8R| | |
54+
|0x400200| |Frequency| |Vol|Mode|Filt Mode|Filt Cutoff|Reso/ BW|L/R Vol|(Reserved)| | | | | | | |CH9| |
55+
|0x400210| |PCM Addr S (or Waveform)| | |PCM Addr E (or Waveform)| | |PCM Addr LS (or Waveform)| | |Waveform (or not used)| | | | | | | | |
56+
|0x400220| |Waveform (or not used)| | | | | | | | | | | | | | | | | |
57+
|0x400230| |Frequency| |Vol|Mode|Filt Mode|Filt Cutoff|Reso/ BW|L/R Vol|(Reserved)| | | | | | | |CH10| |
58+
|0x400240| |PCM Addr S (or Waveform)| | |PCM Addr E (or Waveform)| | |PCM Addr LS (or Waveform)| | |Waveform (or not used)| | | | | | | | |
59+
|0x400250| |Waveform (or not used)| | | | | | | | | | | | | | | | | |
60+
|0x400260| |Frequency| |Vol|Mode|Filt Mode|Filt Cutoff|Reso/ BW|L/R Vol|(Reserved)| | | | | | | |CH11| |
61+
|0x400270| |PCM Addr S (or Waveform)| | |PCM Addr E (or Waveform)| | |PCM Addr LS (or Waveform)| | |Waveform (or not used)| | | | | | | | |
62+
|0x400280| |Waveform (or not used)| | | | | | | | | | | | | | | | | |
63+
|0x400290| |Frequency| |Vol|Mode|Filt Mode|Filt Cutoff|Reso/ BW|L/R Vol|(Reserved)| | | | | | | |CH12| |
64+
|0x4002A0| |PCM Addr S (or Waveform)| | |PCM Addr E (or Waveform)| | |PCM Addr LS (or Waveform)| | |Waveform (or not used)| | | | | | | | |
65+
|0x4002B0| |Waveform (or not used)| | | | | | | | | | | | | | | | | |
66+
|0x4002C0| |Comp Enable|EQ Enable|Comp Thres|Comp Ratio|Comp Volume|EQ Low|EQ Mid|EQ High|Comp RateU|Comp RateL| | | | | | | | |
67+
|0x4002D0| |CH1 Mute|CH2 Mute|CH3 Mute|CH4 Mute|CH5 Mute|CH6 Mute|CH7 Mute|CH8 Mute|CH9 Mute|CH10 Mute|CH11 Mute|CH12 Mute| | | | | | |
68+
|0x4002E0| | | | | | | | | | | | | | | | | | | |
69+
|0x4002F0| | | | | | | | | | | | | | | | | | | |
70+
|0x400300| | | | | | | | | | | | | | | | | | | |
71+
|0x400310| | | | | | | | | | | | | | | | | | | |
72+
|0x400320| | | | | | | | | | | | | | | | | | | |
73+
|0x400330| | | | | | | | | | | | | | | | | | | |
74+
|0x400340| | | | | | | | | | | | | | | | | | | |
75+
|0x400350| | | | | | | | | | | | | | | | | | | |
76+
|0x400360| | | | | | | | | | | | | | | | | | | |
77+
|0x400370| | | | | | | | | | | | | | | | | | | |
78+
|0x400380| | | | | | | | | | | | | | | | | | | |
79+
|0x400390| | | | | | | | | | | | | | | | | | | |
80+
|0x4003A0| | | | | | | | | | | | | | | | | | | |
81+
|0x4003B0| | | | | | | | | | | | | | | | | | | |
82+
|0x4003C0| | | | | | | | | | | | | | | | | | | |
83+
|0x4003D0| | | | | | | | | | | | | | | | | | | |
84+
|0x4003E0| | | | | | | | | | | | | | | | | | | |

src/DrumKeymapManager.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// DrumKeymapManager.cpp
2+
#include "DrumKeymapManager.h"
3+
4+
void DrumKeymapManager::assignNoteToSample(uint8_t midiChannel, uint8_t noteNumber, int32_t pcmIndex, int32_t sampleRate, int32_t pcmLength) {
5+
keymapTable[midiChannel][noteNumber] = DrumSampleInfo{pcmIndex, sampleRate, pcmLength};
6+
printf("[DrumKeymapManager] Assigned note %d on channel %d to PCM index 0x%X, sample rate %d, length %d\n", noteNumber, midiChannel, pcmIndex, sampleRate, pcmLength);
7+
}
8+
9+
DrumSampleInfo DrumKeymapManager::getSampleInfo(uint8_t midiChannel, uint8_t noteNumber) const {
10+
auto chIt = keymapTable.find(midiChannel);
11+
if (chIt == keymapTable.end()) return DrumSampleInfo{-1, -1, -1};
12+
auto noteIt = chIt->second.find(noteNumber);
13+
if (noteIt == chIt->second.end()) return DrumSampleInfo{-1, -1, -1};
14+
return noteIt->second;
15+
}
16+
17+
// ドラムサンプル再生トリガー
18+
void DrumKeymapManager::triggerDrumSample(uint8_t midiChannel, uint8_t noteNumber, uint8_t velocity) {
19+
DrumSampleInfo info = getSampleInfo(midiChannel, noteNumber);
20+
if (info.pcmIndex >= 0) {
21+
// 実際のPCM再生処理をここに記述(例: DrumPcmSampleLoader等を呼び出し)
22+
printf("[DrumKeymapManager] CH%d Note%d → PCM idx=0x%X rate=%d len=%d vel=%d\n",
23+
midiChannel, noteNumber, info.pcmIndex, info.sampleRate, info.pcmLength, velocity);
24+
// TODO: DrumPcmSampleLoader等の再生関数呼び出し
25+
} else {
26+
printf("[DrumKeymapManager] CH%d Note%d 未割当\n", midiChannel, noteNumber);
27+
}
28+
}
29+
30+
void DrumKeymapManager::initializeGM() {
31+
// GMドラムノート番号の例(35:Acoustic Bass Drum, 36: Bass Drum 1, ...)
32+
// 必要に応じて拡張
33+
// 自動割り当てに変更
34+
}

src/DrumKeymapManager.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// DrumKeymapManager.h
2+
#pragma once
3+
#include <unordered_map>
4+
#include <vector>
5+
#include <cstdint>
6+
7+
struct DrumSampleInfo {
8+
int32_t pcmIndex;
9+
int32_t sampleRate;
10+
int32_t pcmLength;
11+
};
12+
13+
class DrumKeymapManager {
14+
public:
15+
// ドラムチャンネルごとにノート→PCM情報を管理
16+
void assignNoteToSample(uint8_t midiChannel, uint8_t noteNumber, int32_t pcmIndex, int32_t sampleRate, int32_t pcmLength);
17+
DrumSampleInfo getSampleInfo(uint8_t midiChannel, uint8_t noteNumber) const;
18+
// ドラムサンプル再生トリガー
19+
void triggerDrumSample(uint8_t midiChannel, uint8_t noteNumber, uint8_t velocity);
20+
21+
// GMドラム初期化
22+
void initializeGM();
23+
24+
private:
25+
// [midiChannel][noteNumber] = DrumSampleInfo
26+
std::unordered_map<uint8_t, std::unordered_map<uint8_t, DrumSampleInfo>> keymapTable;
27+
};

src/DrumPcmSampleLoader.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// DrumPcmSampleLoader.cpp
2+
#include "DrumPcmSampleLoader.h"
3+
#include "DrumKeymapManager.h"
4+
#include <juce_audio_formats/juce_audio_formats.h>
5+
#include <filesystem>
6+
#include <fstream>
7+
#include <iostream>
8+
#include <vector>
9+
#include <cstdint>
10+
#include <cstring>
11+
12+
extern uint8_t* g_pcmRam;
13+
extern size_t g_pcmRamSize;
14+
15+
namespace fs = std::filesystem;
16+
17+
DecodedWav DrumPcmSampleLoader::loadAndDecode(const std::string& filePath) {
18+
// JUCEのAudioFormatManagerを使ってWAV/AIFF/FLAC/MP3等を読み込む
19+
juce::AudioFormatManager formatManager;
20+
formatManager.registerBasicFormats();
21+
22+
juce::File juceFile(filePath);
23+
std::unique_ptr<juce::AudioFormatReader> reader(formatManager.createReaderFor(juceFile));
24+
if (!reader) return {};
25+
26+
std::vector<float> pcm;
27+
int64_t numSamples = reader->lengthInSamples;
28+
int numChannels = reader->numChannels;
29+
pcm.reserve(static_cast<size_t>(numSamples));
30+
31+
juce::AudioBuffer<float> buffer(numChannels, static_cast<int>(numSamples));
32+
reader->read(&buffer, 0, static_cast<int>(numSamples), 0, true, true);
33+
34+
// モノラル化(複数chの場合は平均)
35+
for (int i = 0; i < numSamples; ++i) {
36+
float sum = 0.0f;
37+
for (int ch = 0; ch < numChannels; ++ch) {
38+
sum += buffer.getSample(ch, i);
39+
}
40+
pcm.push_back(sum / numChannels);
41+
}
42+
43+
uint32_t sampleRate = static_cast<uint32_t>(reader->sampleRate);
44+
return DecodedWav{pcm, sampleRate};
45+
}
46+
47+
std::vector<uint8_t> DrumPcmSampleLoader::convertToRaw8bit(const std::vector<float>& input) {
48+
std::vector<uint8_t> out;
49+
out.reserve(input.size());
50+
for (float v : input) {
51+
// -1.0~1.0 → 0~255 にスケール
52+
float clamped = std::min(std::max(v, -1.0f), 1.0f);
53+
uint8_t val = static_cast<uint8_t>((clamped + 1.0f) * 127.5f); // -1→0, 0→127, 1→255
54+
out.push_back(val);
55+
}
56+
return out;
57+
}
58+
59+
bool DrumPcmSampleLoader::loadSampleToRam(const std::string& filePath, uint32_t ramAddress, uint32_t& outSampleRate, uint32_t& outPcmSize) {
60+
auto decoded = loadAndDecode(filePath);
61+
if (decoded.pcm.empty()) return false;
62+
auto raw8 = convertToRaw8bit(decoded.pcm);
63+
if (!g_pcmRam || ramAddress + raw8.size() > g_pcmRamSize) return false;
64+
std::memcpy(g_pcmRam + ramAddress, raw8.data(), raw8.size());
65+
outSampleRate = decoded.sampleRate;
66+
outPcmSize = static_cast<uint32_t>(raw8.size());
67+
return true;
68+
}
69+
70+
// 一括ロード: ./pcm/ ディレクトリ内の[ノート番号].wavを全てロードし、キーマップに登録
71+
void loadAllDrumSamples(DrumKeymapManager& keymap, uint32_t baseRamAddr) {
72+
uint32_t ramPtr = baseRamAddr;
73+
for (int note = 0; note < 128; ++note) {
74+
std::string wavPath = "./pcm/" + std::to_string(note) + ".wav";
75+
if (!fs::exists(wavPath)) {
76+
continue;
77+
}
78+
79+
DrumPcmSampleLoader loader;
80+
uint32_t sampleRate = 44100;
81+
uint32_t pcmSize = 0;
82+
if (loader.loadSampleToRam(wavPath, ramPtr, sampleRate, pcmSize)) {
83+
keymap.assignNoteToSample(10, note, ramPtr, sampleRate, pcmSize); // MIDI ch10
84+
ramPtr += pcmSize; // PCMデータ長分だけポインタを進める
85+
}
86+
}
87+
printf("[DrumPcmSampleLoader] Loaded all drum samples, %d bytes used (%d bytes free)\n", ramPtr - baseRamAddr, g_pcmRamSize - (ramPtr - baseRamAddr));
88+
}

src/DrumPcmSampleLoader.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// DrumPcmSampleLoader.h
2+
#pragma once
3+
#include <string>
4+
#include <vector>
5+
#include <cstdint>
6+
7+
struct DecodedWav {
8+
std::vector<float> pcm;
9+
uint32_t sampleRate;
10+
};
11+
12+
class DrumPcmSampleLoader {
13+
public:
14+
// PCM RAMにRaw Unsigned 8bitで書き込む
15+
bool loadSampleToRam(const std::string& filePath, uint32_t ramAddress, uint32_t& outSampleRate, uint32_t& outPcmSize);
16+
17+
// 任意のPCMデータをRaw Unsigned 8bitに変換
18+
static std::vector<uint8_t> convertToRaw8bit(const std::vector<float>& input);
19+
20+
// サポート: WAV/AIFF/16bit PCM等からのロード
21+
static DecodedWav loadAndDecode(const std::string& filePath);
22+
};
23+
24+
// 一括ロード関数の宣言を追加
25+
void loadAllDrumSamples(class DrumKeymapManager& keymap, uint32_t baseRamAddr = 0);

0 commit comments

Comments
 (0)