Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MSVC support for GigPlayer (rework) #7162

Open
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

Veratil
Copy link
Contributor

@Veratil Veratil commented Mar 26, 2024

Updated form of #6595 as there are too many conflicts to try and resolve in that branch now (I tried for ~1 hour).

Notes:

  • VLAs have been converted to std::array, in the event a Giga sample is loaded which will overload any buffer a std::runtime_error will be thrown; not the best solution but worked the few test gig files I have at least

@Rossmaxx
Copy link
Contributor

@Monospace-V seems to have a few gig files and is looking into the spec. Can you test this one?

@Monospace-V
Copy link
Contributor

Monospace-V commented Mar 28, 2024

One of my files seems to make it crash for some reason. I may look into it when I have more time, but I have multiple gig files, and my file "Tic Tok Men RetroDrums 1.gig" tends to cause issues if I switch to it after using a different gig file, particularly if I am on a non-zero patch before I switch. In this case LMMS seems to tend to crash.
File is available on musical artifacts as RetroDrums One. Would be useful if someone else could check this out since I'm crunched for time presently? If not, I may get to it though, eventually.

Other than this, at first glance, this seems to support pretty decently.

Thank you for altering me to the pr, Rossmaxx. I am simply trying to understand the spec tho I don't actually have much knowledge I'm trying to learn SF2 first but yes. I have a bunch of gig files and this is something I care about

@Rossmaxx
Copy link
Contributor

@Monospace-V can you send that file in here, in a zip.

@Monospace-V
Copy link
Contributor

can you send that file in here, in a zip.

Unfortunately not. Please find it here: https://www.tictokmen.com/sample/

@Veratil
Copy link
Contributor Author

Veratil commented Mar 28, 2024

@Monospace-V looks like the sample buffer isn't large enough at 512, I will bump this up again.

@Veratil
Copy link
Contributor Author

Veratil commented Mar 28, 2024

Oh actually I missed updating the size check (me being dumb and not using a constant)

@Veratil
Copy link
Contributor Author

Veratil commented Mar 28, 2024

After bumping the size here there's no error anymore. 👍

@Monospace-V
Copy link
Contributor

After bumping the size here there's no error anymore. 👍

I'm just wondering what happens if it's even bigger? Like I'm not saying it should be bigger and this might be off topic discussion but is it not possible it could be bigger, or, what stopping it from needing to be larger? Perhaps I don't understand enough.
The gig file format was created for huge instruments, and the GigaSampler just loaded the entire thing into ram iirc

@Veratil
Copy link
Contributor Author

Veratil commented Mar 28, 2024

I'm just wondering what happens if it's even bigger? Like I'm not saying it should be bigger and this might be off topic discussion but is it not possible it could be bigger, or, what stopping it from needing to be larger?

It "slows down" from being on the heap now instead of the stack. We're safe from stack overflows in the worst case situations, but we lose the cache locality of the array. The larger the array the more needs to be moved around. The buffer is at 1Kb right now.

@Rossmaxx
Copy link
Contributor

Would it be a good idea to create an arbitrarily large buffer but keep a todo comment and cleanup the calculation in a follow up pr (or do a refactor in this pr itself)

@Veratil
Copy link
Contributor Author

Veratil commented Mar 29, 2024

There's still some cleanup in this PR left to do.

Copy link
Member

@DomClark DomClark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review is just of the CMake, as it sounds like the C++ changes are still in progress.

The find module isn't working on non-MSVC configurations (I've left comments on it as to why), but this doesn't cause the CI to fail as GIG support is an optional feature. It's out of scope here, but I think we need some way to catch this sort of thing automatically, to avoid problems in the future.

plugins/GigPlayer/CMakeLists.txt Outdated Show resolved Hide resolved
plugins/GigPlayer/CMakeLists.txt Outdated Show resolved Hide resolved
cmake/modules/FindGig.cmake Outdated Show resolved Hide resolved
cmake/modules/FindGig.cmake Outdated Show resolved Hide resolved
cmake/modules/FindGig.cmake Outdated Show resolved Hide resolved
cmake/modules/FindGig.cmake Outdated Show resolved Hide resolved
@Monospace-V
Copy link
Contributor

It "slows down" from being on the heap now instead of the stack. We're safe from stack overflows in the worst case situations, but we lose the cache locality of the array. The larger the array the more needs to be moved around. The buffer is at 1Kb right now.

I don't quite understand, I guess I am not quite at that level yet [: It's all right. I plan to test this pr out again later with the rest of my gig files, try to induce anything. I hope I have enough time. I have a few more gig files I want to try, in the event they induce a crash somehow.

@Veratil
Copy link
Contributor Author

Veratil commented Mar 30, 2024

Rebased on master + address Dom's review

@Monospace-V
Copy link
Contributor

I can stil get this to crash using one of my gig files.
I have a file called maestro_concert_grand_v2.gig.
image
These are the patches.
Patches number 4 (effects) and 5 (mcg_key_release) appear to be silent for reasons I don't quite know.
Switching to patch 5 freezes and crashes LMMS.
It can be downloaded here: https://musical-artifacts.com/artifacts/73?class=related-link

@Veratil
Copy link
Contributor Author

Veratil commented Apr 1, 2024

Alright, I'll look into them. Thanks!

@Veratil
Copy link
Contributor Author

Veratil commented Apr 1, 2024

I confirmed I can't hear anything with patch 4, and patch 5 overloads the bounds of the arrays (by a lot, 38k sized array for example). I'm testing another idea for the buffers. 👍

@Veratil
Copy link
Contributor Author

Veratil commented Apr 6, 2024

@Monospace-V so I've found out that when the buffers are actually sized properly, patch 4 and 5 actually do make sounds.
Patch 4: Turn gain and volume to max and play C0, D0, or E0
Patch 5: Turn gain and volume to max and play any note between A0 and C8, upon release of the key you should hear it
Patch 6: Turn gain and volume to max and play any note between A0 and C8 and it should be the same as Patch 5 but ever so slightly louder

@Veratil
Copy link
Contributor Author

Veratil commented Apr 10, 2024

Well apparently we're not actually C++17 ready on linux and mingw builds.

@Veratil
Copy link
Contributor Author

Veratil commented Apr 10, 2024

Looking around, seems like std::for_each_n was not added until GCC 8 GCC 9.3 (I searched through git tags until I found it). Fun stuff.

@Veratil
Copy link
Contributor Author

Veratil commented Apr 10, 2024

mingw failures are because the CI running 18.04 has installed libgig-4.0.0, which apparently is right before 4.0.0.svn3 where RIFF::file_offset_t was added (what gig::file_offset_t is typedef'd from).

@Rossmaxx
Copy link
Contributor

mingw failures are because the CI running 18.04 has installed libgig-4.0.0, which apparently is right before 4.0.0.svn3 where RIFF::file_offset_t was added (what gig::file_offset_t is typedef'd from)

Can't you use an ifdef for now, with a todo comment, atleast to get the CI working.

@Veratil
Copy link
Contributor Author

Veratil commented Apr 14, 2024

Can't you use an ifdef for now, with a todo comment, atleast to get the CI working.

The issue is getting the libgig version. There is no define in the code to tell it.

@Rossmaxx
Copy link
Contributor

Rossmaxx commented May 22, 2024

mingw failures are because the CI running 18.04 has installed libgig-4.0.0, which apparently is right before 4.0.0.svn3 where RIFF::file_offset_t was added (what gig::file_offset_t is typedef'd from).

#7259 should fix this.

@FyiurAmron
Copy link
Contributor

mingw failures are because the CI running 18.04 has installed libgig-4.0.0, which apparently is right before 4.0.0.svn3 where RIFF::file_offset_t was added (what gig::file_offset_t is typedef'd from).

#7259 should fix this.

As MinGW libgig is provided by tobydox repo, I'm afraid it won't and doesn't; the highest version there is simply 4.0.0 ; bumping Ubuntu version does help Linux builds w.r.t. this, but not MinGW ones.

@Rossmaxx
Copy link
Contributor

I am thinking of taking over this PR and fixing MSVC builds. For now, the idea I have is to disable version checking on MSVC and force the new behaviour explicitly (we have libgig 4.4.0 guaranteed so it's fine)

@Rossmaxx
Copy link
Contributor

Gig player builds on MSVC now, but there seems to be an error while loading files. I'll look into it. @Veratil can you help me with this? It's still fine if you don't.

@Rossmaxx
Copy link
Contributor

but there seems to be an error while loading files.

nvm. A clean rebuild fixed it.

Copy link
Member

@messmerd messmerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick review

plugins/GigPlayer/GigPlayer.h Outdated Show resolved Hide resolved
plugins/GigPlayer/GigPlayer.cpp Outdated Show resolved Hide resolved
plugins/GigPlayer/GigPlayer.cpp Outdated Show resolved Hide resolved
@@ -440,50 +430,44 @@ void GigInstrument::play( SampleFrame* _working_buffer )
samples = frames / freq_factor + Sample::s_interpolationMargins[m_interpolation];
}

const auto neededCapacity = static_cast<std::vector<SampleFrame>::size_type>(samples);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

samples is already std::size_t so it looks like there's no need for the static cast. And the neededCapacity variable may be unnecessary if you can just use samples.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

unsigned long allocationsize = samples * sample.sample->FrameSize;
int8_t buffer[allocationsize];
const auto allocationSize = samples * sample.sample->FrameSize;
const auto neededCapacity = static_cast<std::vector<int8_t>::size_type>(allocationSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allocationSize is already std::size_t so it looks like there's no need for the static cast. And the neededCapacity variable may be unnecessary if you can just use allocationSize.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would defer this point to @Veratil whenever he returns as I don't know about the inner workings.

Comment on lines +1163 to +1164
/* .data_in */ reinterpret_cast<const float*>(oldBuf.data()),
/* .data_out */ reinterpret_cast<float*>(newBuf.data()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* .data_in */ reinterpret_cast<const float*>(oldBuf.data()),
/* .data_out */ reinterpret_cast<float*>(newBuf.data()),
/* .data_in */ oldBuf[0].data(),
/* .data_out */ newBuf[0].data(),

I believe this is possible now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this too


// Delete ended notes (either in the completed state or all the samples ended)
if( it->state == GigState::Completed || it->samples.empty() )
// TODO: C++20 std::erase_if
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@messmerd does #7554 add this functionality?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the member function erase_if will be available, and in GCC 10 the free function will also be available.

@Rossmaxx
Copy link
Contributor

Files don't seem to load properly on msvc now.

@@ -3,15 +3,34 @@ if(LMMS_HAVE_GIG)
include_directories(SYSTEM ${GIG_INCLUDE_DIRS})
SET(CMAKE_AUTOUIC ON)

# Version checking logic disabled for msvc as vcpkg guarantees gig > 4.3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to do version checking unconditionally as a sanity check. It's less complicated that way, makes fewer assumptions about our CI, and would catch any future mistakes.

Plus, if someone tried to build lmms on their own with MSVC, we'd want it to detect if they had an unsupported libgig version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version checking is broken on MSVC and causes a build fail, that's why I brought in this workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MSVC support
6 participants