Skip to content

Commit 69b06f4

Browse files
committed
1. increase some resource in case we can play millions voices midi file
2. also enable AUTO_REDUCE_VOICE_ALLOW for large midi 3. fixed large midi load too slow issue 4. many small fixed 5. update libmidi version to 2.15.3, immidi app up to 1.0.2 6. update imgui and fixed build since we change some API
1 parent 81fccf4 commit 69b06f4

File tree

10 files changed

+80
-66
lines changed

10 files changed

+80
-66
lines changed

CMakeLists.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ set(CMAKE_CXX_STANDARD 14)
55
option(USE_STATIC "Set to ON to build Static Library" OFF)
66
option(USE_IMGUI "Set to ON to build with imgui test" ON)
77

8-
set(PROJECT_VER_PATCH 1)
9-
set(PROJECT_VER_MINOR 0)
108
set(PROJECT_VER_MAJOR 1)
9+
set(PROJECT_VER_MINOR 0)
10+
set(PROJECT_VER_PATCH 2)
1111
set(PROJECT_VER "${PROJECT_VER_MAJOR}.${PROJECT_VER_MINOR}.${PROJECT_VER_PATCH}")
1212

1313

1414
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations -Wno-writable-strings")
1515
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-writable-strings")
1616

17-
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|x86_64)")
17+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|x86_64|AMD64)")
1818
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mavx")
1919
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2 -mavx")
20-
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -msse4.1 -mssse3 -msse2 -msse")
21-
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -msse4.1 -mssse3 -msse2 -msse")
20+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -msse4.1 -mssse3 -msse2 -msse")
21+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -msse4.1 -mssse3 -msse2 -msse")
2222
endif()
2323

2424
if (APPLE)

imgui

Submodule imgui updated from 22f467f to bd34499

libmidi/CMakeLists.txt

+27-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,30 @@ find_package(PkgConfig)
2222
find_package(Curses REQUIRED)
2323
pkg_search_module(SDL2 REQUIRED sdl2)
2424

25+
if (APPLE)
26+
message(STATUS "libmidi(Apple) Use OpenMP")
27+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xpreprocessor -fopenmp")
28+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Xpreprocessor -fopenmp")
29+
set(LINK_LIBS ${LINK_LIBS} -L/usr/local/lib -lomp pthread)
30+
else()
31+
find_package(OpenMP)
32+
if(NOT TARGET OpenMP::OpenMP_CXX)
33+
set_property(TARGET OpenMP::OpenMP_CXX
34+
PROPERTY INTERFACE_LINK_LIBRARIES ${OpenMP_CXX_FLAGS} Threads::Threads)
35+
endif()
36+
if(WIN32 OR MINGW)
37+
message(STATUS "libmidi(Windows) Use OpenMP")
38+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
39+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
40+
set(LINK_LIBS ${LINK_LIBS} gmp pthread)
41+
else()
42+
message(STATUS "libmidi Use OpenMP")
43+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
44+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
45+
set(LINK_LIBS ${LINK_LIBS} gmp pthread)
46+
endif()
47+
endif()
48+
2549
set(MIDI_INC_DIRS
2650
${CMAKE_CURRENT_SOURCE_DIR}
2751
)
@@ -130,14 +154,14 @@ include_directories(${MIDI_INC_DIRS})
130154

131155
set(MIDI_VERSION_MAJOR 2)
132156
set(MIDI_VERSION_MINOR 15)
133-
set(MIDI_VERSION_PATCH 2)
157+
set(MIDI_VERSION_PATCH 3)
134158
set(MIDI_VERSION_STRING ${MIDI_VERSION_MAJOR}.${MIDI_VERSION_MINOR}.${MIDI_VERSION_PATCH})
135159

136160
if (USE_STATIC)
137161
ADD_LIBRARY(midi STATIC ${MIDI_SOURCE_FILES} ${MIDI_HEADER_FILES})
138162
else()
139163
ADD_LIBRARY(midi SHARED ${MIDI_SOURCE_FILES} ${MIDI_HEADER_FILES})
140-
target_link_libraries(midi ${EXTRA_LIBS})
164+
target_link_libraries(midi ${EXTRA_LIBS} ${LINK_LIBS})
141165
set_property(TARGET midi PROPERTY POSITION_INDEPENDENT_CODE ON)
142166
set_target_properties(midi PROPERTIES VERSION ${MIDI_VERSION_STRING} SOVERSION ${MIDI_VERSION_MAJOR})
143167
endif()
@@ -146,7 +170,7 @@ endif()
146170
if((IOS AND CMAKE_OSX_ARCHITECTURES MATCHES "arm") OR (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64)"))
147171
message(STATUS "Target arch: arm")
148172
target_compile_options(midi PRIVATE -mfloat-abi=softfp -mfpu=neon -march=armv7 -ftree-vectorize -fpermissive -fomit-frame-pointer -funroll-loop)
149-
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|x86_64)")
173+
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|x86_64|AMD64)")
150174
message(STATUS "Target arch: x86")
151175
if(MSVC OR MSVC_IDE)
152176
target_compile_options(midi PRIVATE /arch:AVX2 /arch:AVX /arch:FMA)

libmidi/common.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1892,7 +1892,7 @@ int load_font_from_cfg(char* name)
18921892
return errcnt;
18931893
}
18941894

1895-
#define MIDI_VERSION "2.15.0"
1895+
#define MIDI_VERSION "2.15.3"
18961896
#ifndef PACKAGE_VERSION
18971897
#define PACKAGE_VERSION MIDI_VERSION
18981898
#endif

libmidi/common.h

+5-23
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
/* you cannot but use safe_malloc(). */
9292
#define HAVE_SAFE_MALLOC 1
9393
/* malloc's limit */
94-
#define MAX_SAFE_MALLOC_SIZE (1 << 26) /* 64M, if midi file including millions voices, need increase memory size */
94+
#define MAX_SAFE_MALLOC_SIZE (1 << 27) /* 128M, if midi file including millions voices, need increase memory size */
9595

9696
/* type of floating point number */
9797
//typedef double FLOAT_T;
@@ -119,7 +119,7 @@ typedef float FLOAT_T;
119119
configurable by the command line option (-p) from 1 to until memory is
120120
allowed. If your machine has much CPU power, millions voices midi file
121121
maybe need set to 16384 */
122-
#define DEFAULT_VOICES 512
122+
#define DEFAULT_VOICES 16384
123123

124124
/* The size of the internal buffer is 2^AUDIO_BUFFER_BITS samples.
125125
This determines maximum number of samples ever computed in a row.
@@ -177,24 +177,6 @@ typedef float FLOAT_T;
177177
#define DEFAULT_RATE 48000
178178
#endif /* DEFAULT_RATE */
179179

180-
/* The size of the internal buffer is 2^AUDIO_BUFFER_BITS samples.
181-
This determines maximum number of samples ever computed in a row.
182-
183-
For Linux and FreeBSD users:
184-
185-
This also specifies the size of the buffer fragment. A smaller
186-
fragment gives a faster response in interactive mode -- 10 or 11 is
187-
probably a good number. Unfortunately some sound cards emit a click
188-
when switching DMA buffers. If this happens to you, try increasing
189-
this number to reduce the frequency of the clicks.
190-
191-
For other systems:
192-
193-
You should probably use a larger number for improved performance.
194-
195-
*/
196-
#define AUDIO_BUFFER_BITS 12 /* Maxmum audio buffer size (2^bits) */
197-
198180
/* 1000 here will give a control ratio of 22:1 with 22 kHz output.
199181
Higher CONTROLS_PER_SECOND values allow more accurate rendering
200182
of envelopes and tremolo. The cost is CPU time. */
@@ -242,10 +224,10 @@ typedef float FLOAT_T;
242224
#define USE_LDEXP
243225

244226
/* Define the pre-resampling cache size.
245-
* This value is default. You can change the cache saze with
227+
* This value is default. You can change the cache size with
246228
* command line option.
247229
*/
248-
#define DEFAULT_CACHE_DATA_SIZE (4 * 1024 * 1024)
230+
#define DEFAULT_CACHE_DATA_SIZE (16 * 1024 * 1024)
249231

250232
/* Where do you want to put temporary file into ?
251233
* If you are in UNIX, you can undefine this macro. If TMPDIR macro is
@@ -339,7 +321,7 @@ typedef float FLOAT_T;
339321

340322
/* Define if you want to allow auto reduce voice.
341323
*/
342-
//#define AUTO_REDUCE_VOICE_ALLOW
324+
#define AUTO_REDUCE_VOICE_ALLOW
343325

344326
//#define HAVE_POPEN
345327

libmidi/playmidi.c

+2
Original file line numberDiff line numberDiff line change
@@ -7729,6 +7729,7 @@ static void do_compute_data_midi(int32 count)
77297729
memset(reverb_buffer, 0, chbufidx);
77307730
}
77317731
for (i = 0; i < uv; i++)
7732+
{
77327733
if (voice[i].status != VOICE_FREE)
77337734
{
77347735
int32 *vpb;
@@ -7755,6 +7756,7 @@ static void do_compute_data_midi(int32 count)
77557756
ctl_note_event(i);
77567757
}
77577758
}
7759+
}
77587760

77597761
while (uv > 0 && voice[uv - 1].status == VOICE_FREE)
77607762
uv--;

libmidi/resample.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static double newt_recip[60] = {0, 1, 1.0 / 2, 1.0 / 3, 1.0 / 4, 1.0 / 5, 1.0 /
272272
1.0 / 57, 1.0 / 58, 1.0 / 59};
273273
static sample_t *newt_old_src = NULL;
274274

275-
static resample_t resample_newton(sample_t *src, splen_t ofs, resample_rec_t *rec)
275+
static inline resample_t resample_newton(sample_t *src, splen_t ofs, resample_rec_t *rec)
276276
{
277277
int n_new, n_old;
278278
int32 v1, v2, diff = 0;
@@ -357,7 +357,7 @@ static resample_t resample_newton(sample_t *src, splen_t ofs, resample_rec_t *re
357357

358358
/* Simple linear interpolation */
359359

360-
static resample_t resample_linear(sample_t *src, splen_t ofs, resample_rec_t *rec)
360+
static inline resample_t resample_linear(sample_t *src, splen_t ofs, resample_rec_t *rec)
361361
{
362362
int32 v1, v2, ofsi;
363363

@@ -369,7 +369,7 @@ static resample_t resample_linear(sample_t *src, splen_t ofs, resample_rec_t *re
369369

370370
/* No interpolation -- Earplugs recommended for maximum listening enjoyment */
371371

372-
static resample_t resample_none(sample_t *src, splen_t ofs, resample_rec_t *rec)
372+
static inline resample_t resample_none(sample_t *src, splen_t ofs, resample_rec_t *rec)
373373
{
374374
return src[ofs >> FRACTION_BITS];
375375
}
10.4 MB
Binary file not shown.

test/Info.plist

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@
3232
<key>CFBundleInfoDictionaryVersion</key>
3333
<string>6.0</string>
3434
<key>CFBundleLongVersionString</key>
35-
<string>2.15.2</string>
35+
<string>1.0.2</string>
3636
<key>CFBundleName</key>
3737
<string>immidi</string>
3838
<key>CFBundlePackageType</key>
3939
<string>APPL</string>
4040
<key>CFBundleShortVersionString</key>
41-
<string>2.15</string>
41+
<string>1.0</string>
4242
<key>CFBundleVersion</key>
43-
<string>2.15.2</string>
43+
<string>1.0.2</string>
4444
<key>CSResourcesFileMapped</key>
4545
<true/>
4646
<key>LSAppNapIsDisabled</key>

test/immidi.cpp

+33-27
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ static int cmsg(int type, int verbosity_level, char *fmt, ...);
281281
static void ctl_event(CtlEvent *e);
282282
std::mutex event_mutex;
283283
std::mutex data_mutex;
284+
static bool m_loading = false;
284285
static bool m_running = false;
285286
static bool m_converting = false;
286287
static bool m_paused = false;
@@ -616,9 +617,24 @@ static void reset_channels()
616617
for (int i = 0; i < MAX_CHANNELS; i++)
617618
{
618619
midi_channels[i].events.clear();
619-
memset(&midi_channels[i], 0, sizeof(MIDIChannel));
620+
midi_channels[i].key_board.reset();
621+
memset(midi_channels[i].instrum_name, 0, 128);
622+
midi_channels[i].velocity = 0;
623+
midi_channels[i].volume = 0;
624+
midi_channels[i].expression = 0;
625+
midi_channels[i].program = 0;
620626
midi_channels[i].panning = 64;
621627
midi_channels[i].pitchbend = 0x2000;
628+
midi_channels[i].sustain = 0;
629+
midi_channels[i].wheel = 0;
630+
midi_channels[i].mute = 0;
631+
midi_channels[i].bank = 0;
632+
midi_channels[i].bank_lsb = 0;
633+
midi_channels[i].bank_msb = 0;
634+
midi_channels[i].is_drum = 0;
635+
midi_channels[i].bend_mark = 0;
636+
midi_channels[i].check_mute = false;
637+
midi_channels[i].check_solo = false;
622638
}
623639
}
624640

@@ -629,21 +645,6 @@ static void reset_events()
629645
cuepoint_pending = 0;
630646
}
631647

632-
static std::vector<MIDI_Event>::iterator find_last(int channel, int note)
633-
{
634-
std::vector<MIDI_Event>::iterator it = midi_channels[channel].events.end();
635-
while (it != midi_channels[channel].events.begin())
636-
{
637-
it --;
638-
if (it->note == note && isnan(it->end_time))
639-
{
640-
return it;
641-
}
642-
}
643-
644-
return it;
645-
}
646-
647648
static void parser_events(MidiEvent * events)
648649
{
649650
if (events)
@@ -679,10 +680,11 @@ static void parser_events(MidiEvent * events)
679680
}
680681
else if (type == ME_NOTEOFF)
681682
{
682-
std::vector<MIDI_Event>::iterator it = find_last(ch, note);
683-
if (it != midi_channels[ch].events.end())
683+
if (midi_channels[ch].events.size() > 0)
684684
{
685-
it->end_time = (float)time / play_mode->rate;
685+
std::vector<MIDI_Event>::iterator it = midi_channels[ch].events.end() - 1;
686+
if (isnan(it->end_time))
687+
it->end_time = (float)time / play_mode->rate;
686688
}
687689
}
688690
else if (type == ME_ALL_NOTES_OFF)
@@ -798,12 +800,14 @@ static void ctl_event(CtlEvent *e)
798800
switch (e->type)
799801
{
800802
case CTLE_NOW_LOADING: /* v1:filename */
803+
m_loading = true;
801804
break;
802805
case CTLE_LOADING_DONE: /* v1:0=success -1=error 1=terminated */
803806
if (e->v1 == 0)
804807
{
805808
parser_events((MidiEvent *)e->v2);
806809
}
810+
m_loading = false;
807811
break;
808812
case CTLE_PLAY_START: /* v1:nsamples */
809813
m_running = true;
@@ -1408,7 +1412,7 @@ static void ShowMediaScopeView(int index, ImVec2 pos, ImVec2 size)
14081412
if (!channel_data[i].m_wave.empty())
14091413
{
14101414
ImGui::PushID(i);
1411-
ImGui::PlotLines("##wave", (float *)channel_data[i].m_wave.data, channel_data[i].m_wave.w, 0, nullptr, -1.0 / AudioWaveScale , 1.0 / AudioWaveScale, channel_view_size, 4, false, false);
1415+
ImGui::PlotLinesEx("##wave", (float *)channel_data[i].m_wave.data, channel_data[i].m_wave.w, 0, nullptr, -1.0 / AudioWaveScale , 1.0 / AudioWaveScale, channel_view_size, 4, false, false);
14121416
ImGui::PopID();
14131417
}
14141418
draw_list->AddRect(channel_min, channel_max, COL_SLIDER_HANDLE, 0);
@@ -1561,7 +1565,7 @@ static void ShowMediaScopeView(int index, ImVec2 pos, ImVec2 size)
15611565
if (!channel_data[i].m_fft.empty())
15621566
{
15631567
ImGui::PushID(i);
1564-
ImGui::PlotLines("##fft", (float *)channel_data[i].m_fft.data, channel_data[i].m_fft.w, 0, nullptr, 0.0, 1.0 / AudioFFTScale, channel_view_size, 4, true, true);
1568+
ImGui::PlotLinesEx("##fft", (float *)channel_data[i].m_fft.data, channel_data[i].m_fft.w, 0, nullptr, 0.0, 1.0 / AudioFFTScale, channel_view_size, 4, true, true);
15651569
ImGui::PopID();
15661570
}
15671571
draw_list->AddRect(channel_min, channel_max, COL_SLIDER_HANDLE, 0);
@@ -1635,7 +1639,7 @@ static void ShowMediaScopeView(int index, ImVec2 pos, ImVec2 size)
16351639
ImGui::PushID(i);
16361640
ImGui::ImMat db_mat_inv = channel_data[i].m_db.clone();
16371641
db_mat_inv += 90.f;
1638-
ImGui::PlotLines("##db", (float *)db_mat_inv.data, db_mat_inv.w, 0, nullptr, 0, 90.f / AudioDBScale, channel_view_size, 4, false, true);
1642+
ImGui::PlotLinesEx("##db", (float *)db_mat_inv.data, db_mat_inv.w, 0, nullptr, 0, 90.f / AudioDBScale, channel_view_size, 4, false, true);
16391643
ImGui::PopID();
16401644
}
16411645
draw_list->AddRect(channel_min, channel_max, COL_SLIDER_HANDLE, 0);
@@ -2102,7 +2106,7 @@ bool Application_Frame(void * handle, bool app_will_quit)
21022106
ImGui::SetNextWindowPos(control_pos, ImGuiCond_Always);
21032107
if (ImGui::BeginChild("##Control_Panel_Window", control_size, false, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings))
21042108
{
2105-
ImGui::BeginDisabled(m_running);
2109+
ImGui::BeginDisabled(m_running || m_loading);
21062110
// File Dialog
21072111
if (ImGuiFileDialog::Instance()->Display("embedded", ImGuiWindowFlags_NoCollapse, ImVec2(0,0), ImVec2(0,400)))
21082112
{
@@ -2130,7 +2134,7 @@ bool Application_Frame(void * handle, bool app_will_quit)
21302134
ImGui::Separator();
21312135
// Setting
21322136
// Select SoundFont
2133-
ImGui::BeginDisabled(m_running);
2137+
ImGui::BeginDisabled(m_running || m_loading);
21342138
int _index = sf_index;
21352139
if (ImGui::Combo("Select Sound Font", &_index, &Funcs::ItemGetter, &sf_name_list, sf_name_list.size()))
21362140
{
@@ -2303,6 +2307,7 @@ bool Application_Frame(void * handle, bool app_will_quit)
23032307
ImGui::BeginDisabled(!midi_is_selected);
23042308
ImGui::SetWindowFontScale(2.0);
23052309
ImGui::SetCursorScreenPos(control_view_pos + ImVec2(20 + time_area_x, (control_view_size.y - 64) / 2));
2310+
ImGui::BeginDisabled(m_loading);
23062311
if (ImGui::Button(m_running ? (m_paused ? ICON_FA_PLAY : ICON_FA_PAUSE) : ICON_FA_PLAY "##play_pause", ImVec2(64, 64)))
23072312
{
23082313
if (!m_running)
@@ -2324,12 +2329,13 @@ bool Application_Frame(void * handle, bool app_will_quit)
23242329
ImGui::SetCursorScreenPos(control_view_pos + ImVec2(20 + time_area_x + 64, (control_view_size.y - 64) / 2));
23252330
if (ImGui::Button(ICON_FA_STOP "##stop", ImVec2(64, 64)))
23262331
{
2327-
if (m_running) push_event(RC_STOP, 0);
2332+
if (m_running || m_loading) push_event(RC_STOP, 0);
23282333
}
23292334
ImGui::ShowTooltipOnHover("%s", "Stop");
23302335
ImGui::EndDisabled();
2336+
ImGui::EndDisabled();
23312337

2332-
ImGui::BeginDisabled(m_running);
2338+
ImGui::BeginDisabled(m_running || m_loading);
23332339
ImGui::SetCursorScreenPos(control_view_pos + ImVec2(20 + time_area_x + 64 + 64, (control_view_size.y - 64) / 2));
23342340
if (ImGui::Button(ICON_FA_FLOPPY_DISK "##save_to wav", ImVec2(64, 64)))
23352341
{
@@ -2366,7 +2372,7 @@ bool Application_Frame(void * handle, bool app_will_quit)
23662372
ImGui::ColorSet tick_color = {white_color, white_color, white_color};
23672373
float knob_size = 84.f;
23682374
float knob_step = NAN;
2369-
ImGui::BeginDisabled(!m_running);
2375+
ImGui::BeginDisabled(!m_running && !m_loading);
23702376
float main_volume = current_MFnode ? current_MFnode->master_volume : 0;
23712377
float drum_power = opt_drum_power;
23722378
float speed = current_MFnode ? current_MFnode->tempo_ratio : 0;

0 commit comments

Comments
 (0)