summarylogtreecommitdiffstats
path: root/midi.patch
blob: 4e0451934bf68e22beca3a2655e9369f411fced7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
commit 33ccf82c744865e5e03e52702686ddb476e51173
Author: Yoann Laissus <yoann.laissus@gmail.com>
Date:   Sun Mar 19 20:59:31 2023 +0100

    Mute metronome for midi output

diff --git a/src/engraving/playback/playbacksetupdataresolver.cpp b/src/engraving/playback/playbacksetupdataresolver.cpp
index 600a991708..99eeacd903 100644
--- a/src/engraving/playback/playbacksetupdataresolver.cpp
+++ b/src/engraving/playback/playbacksetupdataresolver.cpp
@@ -80,9 +80,5 @@ void PlaybackSetupDataResolver::resolveChordSymbolsSetupData(const Instrument* i
 
 void PlaybackSetupDataResolver::resolveMetronomeSetupData(mpe::PlaybackSetupData& result) const
 {
-    static const mpe::PlaybackSetupData METRONOME_SETUP_DATA = {
-        SoundId::Block, SoundCategory::Percussions, { SoundSubCategory::Wooden }, {}
-    };
-
     result = METRONOME_SETUP_DATA;
 }
diff --git a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
index e99c01397e..b9c3b1c1f0 100644
--- a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
+++ b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
@@ -181,11 +181,29 @@ bool FluidSynth::handleEvent(const midi::Event& event)
     }
     }
 
-    midiOutPort()->sendEvent(event);
+    if (!isMetronome()) {
+        midiOutPort()->sendEvent(event);
+    }
 
     return ret == FLUID_OK;
 }
 
+bool FluidSynth::isMetronome() const
+{
+    // There is no easy way to know if this fluidsynth instance is the metronome one
+    // Let's guess it from the channel sound program
+    const std::map<mpe::voice_layer_idx_t, ChannelMap::VoiceMappings>& data = m_sequencer.channels().data();
+    ChannelMap::VoiceMappings mapping = data.at(data.begin()->first);
+    ChannelMap::ChannelMapping channelMapping = mapping.at(mapping.begin()->first);
+    program_t program = channelMapping.second.program;
+
+    std::map<SoundMappingKey, midi::Programs> percussionsMapping = mappingByCategory(METRONOME_SETUP_DATA.category);
+    SoundMappingKey metronomeSoundMapping = { METRONOME_SETUP_DATA.id,  { METRONOME_SETUP_DATA.subCategorySet } };
+    program_t metronomeProgram = percussionsMapping.at(metronomeSoundMapping).begin()->program;
+
+    return program == metronomeProgram;
+}
+
 void FluidSynth::setSampleRate(unsigned int sampleRate)
 {
     if (m_sampleRate == sampleRate) {
diff --git a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.h b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.h
index 90356c5d1a..750dfa9c34 100644
--- a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.h
+++ b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.h
@@ -108,6 +108,8 @@ private:
     int setExpressionLevel(int level);
     int setControllerValue(const midi::Event& event);
 
+    bool isMetronome() const;
+
     std::shared_ptr<Fluid> m_fluid = nullptr;
 
     async::Channel<unsigned int> m_streamsCountChanged;
diff --git a/src/framework/mpe/events.h b/src/framework/mpe/events.h
index 802fb8b2f4..16f7febe1f 100644
--- a/src/framework/mpe/events.h
+++ b/src/framework/mpe/events.h
@@ -373,6 +373,13 @@ static const PlaybackSetupData GENERIC_SETUP_DATA = {
 
 static const String GENERIC_SETUP_DATA_STRING = GENERIC_SETUP_DATA.toString();
 
+static const PlaybackSetupData METRONOME_SETUP_DATA = {
+    SoundId::Block,
+    SoundCategory::Percussions,
+    { SoundSubCategory::Wooden },
+    {}
+};
+
 struct PlaybackData {
     PlaybackEventsMap originEvents;
     PlaybackSetupData setupData;

commit f5b4ba35e0f28466cc0cca757323f48f73ad8c34
Author: Yoann Laissus <yoann.laissus@gmail.com>
Date:   Mon Feb 20 22:11:53 2023 +0100

    Fixes for MIDI output
    
    It wasn't working at all due to incorrect velocity value
    It was using 7 bit values on MIDI 2.0 (16 bit)
    Fluidsynth and platform midi outputs are not compatible yet so we use 1.0

diff --git a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsequencer.cpp b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsequencer.cpp
index d6f4c9d781..e9eea0d89c 100644
--- a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsequencer.cpp
+++ b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsequencer.cpp
@@ -109,20 +109,17 @@ void FluidSequencer::updatePlaybackEvents(EventSequenceMap& destination, const m
             channel_t channelIdx = channel(noteEvent);
             note_idx_t noteIdx = noteIndex(noteEvent.pitchCtx().nominalPitchLevel);
             velocity_t velocity = noteVelocity(noteEvent);
-            tuning_t tuning = noteTuning(noteEvent, noteIdx);
 
-            midi::Event noteOn(Event::Opcode::NoteOn, Event::MessageType::ChannelVoice20);
+            midi::Event noteOn(Event::Opcode::NoteOn, Event::MessageType::ChannelVoice10);
             noteOn.setChannel(channelIdx);
             noteOn.setNote(noteIdx);
             noteOn.setVelocity(velocity);
-            noteOn.setPitchNote(noteIdx, tuning);
 
             destination[timestampFrom].emplace(std::move(noteOn));
 
-            midi::Event noteOff(Event::Opcode::NoteOff, Event::MessageType::ChannelVoice20);
+            midi::Event noteOff(Event::Opcode::NoteOff, Event::MessageType::ChannelVoice10);
             noteOff.setChannel(channelIdx);
             noteOff.setNote(noteIdx);
-            noteOff.setPitchNote(noteIdx, tuning);
 
             destination[timestampTo].emplace(std::move(noteOff));
 
diff --git a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
index 43cc30b4d3..e99c01397e 100644
--- a/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
+++ b/src/framework/audio/internal/synthesizers/fluidsynth/fluidsynth.cpp
@@ -148,6 +148,10 @@ void FluidSynth::createFluidInstance()
 
 bool FluidSynth::handleEvent(const midi::Event& event)
 {
+    if (event.opcode() == Event::Opcode::NoteOn || event.opcode() == Event::Opcode::NoteOff) {
+        LOGD() << "handleEvent: " << event.opcodeString() << " velocity " << event.velocity() << " channel " << event.channel() <<
+            " note " << event.note() << " pitch " << event.pitchTuningCents();
+    }
     int ret = FLUID_OK;
     switch (event.opcode()) {
     case Event::Opcode::NoteOn: {
diff --git a/src/framework/midi/internal/platform/lin/alsamidioutport.cpp b/src/framework/midi/internal/platform/lin/alsamidioutport.cpp
index 55fce02815..829aa51bf1 100644
--- a/src/framework/midi/internal/platform/lin/alsamidioutport.cpp
+++ b/src/framework/midi/internal/platform/lin/alsamidioutport.cpp
@@ -248,6 +248,8 @@ mu::Ret AlsaMidiOutPort::sendEvent(const Event& e)
     snd_seq_ev_set_source(&seqev, 0);
     snd_seq_ev_set_dest(&seqev, SND_SEQ_ADDRESS_SUBSCRIBERS, 0);
 
+    LOGD() << "Sent midi event " << e.to_string();
+
     switch (e.opcode()) {
     case Event::Opcode::NoteOn:
         snd_seq_ev_set_noteon(&seqev, e.channel(), e.note(), e.velocity());