Zynseq - A native step sequencer

I’m away from my home for a couple of days, I will continue testing the séquencer at the end of the week.

Hi @riban!!

I’m just testing the step seq and found some warnings while building the zynseq library:

root@zynthian:/zynthian/zynthian-ui/zynlibs/zynseq/build# make
[ 14%] Building CXX object CMakeFiles/zynseq.dir/zynseq.cpp.o
[ 28%] Building CXX object CMakeFiles/zynseq.dir/pattern.cpp.o
[ 42%] Building CXX object CMakeFiles/zynseq.dir/song.cpp.o
[ 57%] Building CXX object CMakeFiles/zynseq.dir/patternmanager.cpp.o
In file included from /usr/include/c++/8/map:61,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/sequence.h:3,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/patternmanager.h:3,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/patternmanager.cpp:1:
/usr/include/c++/8/bits/stl_map.h: In member function ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = unsigned int; _Tp = Sequence; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_map.h:518:8: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
    __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
/usr/include/c++/8/bits/stl_map.h: In member function ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = unsigned int; _Tp = Sequence; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_map.h:499:8: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
    __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
In file included from /usr/include/c++/8/map:60,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/sequence.h:3,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/patternmanager.h:3,
                 from /zynthian/zynthian-ui/zynlibs/zynseq/patternmanager.cpp:1:
/usr/include/c++/8/bits/stl_tree.h: In member function ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<unsigned int&&>, std::tuple<>}; _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2411:7: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
       _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/8/bits/stl_tree.h: In member function ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const unsigned int&>, std::tuple<>}; _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2411:7: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
/usr/include/c++/8/bits/stl_tree.h: In member function ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::erase(const _Key&) [with _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2518:7: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
       _M_erase_aux(__p.first, __p.second);
       ^~~~~~~~~~~~
/usr/include/c++/8/bits/stl_tree.h: In member function ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const key_type&) [with _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2146:5: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/8/bits/stl_tree.h: In member function ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase_aux(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator) [with _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2500:5: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/8/bits/stl_tree.h:2500:5: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
/usr/include/c++/8/bits/stl_tree.h:2507:4: note: parameter passing for argument of type ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’ changed in GCC 7.1
    _M_erase_aux(__first++);
    ^~~~~~~~~~~~
/usr/include/c++/8/bits/stl_tree.h: In member function ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase_aux(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator) [with _Key = unsigned int; _Val = std::pair<const unsigned int, Sequence>; _KeyOfValue = std::_Select1st<std::pair<const unsigned int, Sequence> >; _Compare = std::less<unsigned int>; _Alloc = std::allocator<std::pair<const unsigned int, Sequence> >]’:
/usr/include/c++/8/bits/stl_tree.h:2486:5: note: parameter passing for argument of type ‘std::_Rb_tree<unsigned int, std::pair<const unsigned int, Sequence>, std::_Select1st<std::pair<const unsigned int, Sequence> >, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Sequence> > >::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const unsigned int, Sequence> >’} changed in GCC 7.1
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ 71%] Building CXX object CMakeFiles/zynseq.dir/sequence.cpp.o
[ 85%] Building CXX object CMakeFiles/zynseq.dir/timebase.cpp.o
[100%] Linking CXX shared library libzynseq.so
[100%] Built target zynseq

Regards

Yep! That’s annoying. I have looked into it but not resolved yet.

The warning relates to a change in GCC which could be incompatible with anything compiled with earlier versions. I don’t think it is bad and could be masked but I haven’t figured out how to configure Cmake to pass the option and also wanted to avoid an option that may be reminded in future.

Btw there is an issue with zynseq I am looking at.

1 Like

That’s because every time @riban gets close to shipping it, the whole zynth build changes around it :joy::joy::joy:

I dunno how, but please, somehow, you need to sync up and get this feature shipped so I have something to do during UK lockdown 3 :- brexapocalypse !

2 Likes

Also shiny thinks that distract me… like calibration.

5 Likes

:raised_hands: :raised_hands: :raised_hands:

3 Likes

Build warnings have now been masked. The issue is that the ABI has changed in gcc 7.1. This may affect code built with earlier gcc that uses the library. zynlib is built with current gcc 8.3.0. It is called by python3 which does not seem to be compiled with gcc. It is probably the ctypes python3 library that needs to be compatible but I haven’t yet found where this lives. There is a chance an incompatibility between the two but I can’t figure out if that is true. For now I have masked the warning. (Fingers in ears and closed eyes means the danger doesn’t exist, right?)

1 Like

I have pushed some updates to the feature/stepseq branch and updated the wiki to match. I think this is pretty close to being ready to ship! Please have a play. Follow the guide on the wiki and let me know of any errors, ommisions or workflows that don’t work as described or could be improved.

If you have used the sequencer before you will notice it has changed quite a lot. It is now focused around the zynpad workflow. There are future enhancements planned to add a linear, multitrack sequencer. You should be able to drive it entirely from touchscreen or encoders. You can use keyboard binding to emulate the encoders.

I think I have addressed most of the suggestions from @jofemodo. I await his input on integration with snapshots (not yet implemented). Master branch has been merged into feature branch today so this feature branch should include all the newness including touchscreen calibration.

There are bound to be bugs so do let me know. I also have some work to do around optimsation but this should be useable, at least to test the workflows and functionality.

A bit late (or very early) for you Christmas box.

5 Likes

Exciting!

1 quick question… do we expect save file format to remain the same from now? If this is the final shakedown before it ships, I’ll give it a go :+1:

Thank you, Santa. :santa::santa::santa:

It depends on what @jofemodo suggests for integration with snapshots. There is a file format version so as long as we stick with the RIFF format, even if it changes we can detect and transform old files. It doesn’t support the original format used in alpha but the more recent development versions are supported.

[Edit]I would suggest that you avoid relying on zynseq for production (performance) until it is on the stable release. I will attempt to maintain backwards compatibility but until then, no guarantees.

1 Like

Hi

This is an update that is only tangentally related to zynseq. I have written a Standard MIDI File library: zynsmf. This can load one or more .mid files, parse their content, provide information (like duration) and play one of them. In the latest update to the feature/stepseq branch, zynsmf replaces jack-smf-player to play SMF and mutagen to parse SMF for their duration. The key improvments are:

  • Populating the list of MIDI files is now faster (which may only be noticable for very large files)
  • Stopping playback should not trigger xrun
  • Better integration with tempo control

I haven’t yet found a .mid file with varying tempo (they all seem to be 120bpm) so haven’t fully tested the tempo handling. Beware that playing a MIDI file will change your tempo if it has tempo markers.

Limitations;

  • SMF format 0 & 1 are handled. In theory format 2 should also work but that is relatively unused and not intended for linear playback.
  • SMF using SMPTE time is not supported but is on the list to resolve. Again, this is rarely used.
  • SysEx is silently ignored - I can add it if required but not currently of much use within Zynthian
  • Meta data events are parsed and stored but not presented in the Zynthian UI. We could have a popup screen that shows this meta data but that is rather low priority. (Meta data can include information like song, track, instrument names, etc.)
  • Recording not yet implemented
  • Format 1 files with multiple tracks are handled but presented as a single schedule of events. It may be useful to be able to manage tracks individually, like a DAW, e.g. mute, solo, etc.

I will start working on the recording side of it now with the aim to replace jack-midi-recorder and will also use it to import MIDI to step sequencer so that we only use one library for all SMF operations. This brings this element within our control and has better consistency of SMF handling.

Please do try this and let me know any issues.

10 Likes

Thanks for that., once the January work deluge has subsided I’ll unleash the 3 or 4 MIDI files of interest I have at the moment on it and see how far I get…

SMF recorder now implemented - please try it.

Also stopping player does not clear all sounds. It now sends relevant note-off and controller reset messges.

2 Likes

I’ve seen on github that you’ve commited a lot on the stepseq branch.
I really have to find some time to spend on this. But that hard for me these days.

Hello everyone. I don’t know if this is only my problem but when testing the sequencer i’m able to use only ZynAddSubFX and LinuxSampler. I haven’t tried everything else but other instruments can’t produce any sound when loaded. Another problem is that it’s impossible to add Audio-FXs to the layers. Everything freezes when i do that. No problems when using master ui.

Is that with the feature/stepseq branch? I haven’t tested with those engines. I tend to use fluidsynth which works fine for me.

I just tried a few engines, all fine and was able to add audio layer.

Yes, only with the stepseq branch. I don’t know with fluidsynth. I will try

I’m not seeing any of those problems. Tell me a step-by-step list of directions to reproduce issue, starting with empty config (no layers).

Hi @zynthianers!

I’m super-excited with the upcoming of the new version of stepseq. I hoped to merge with master this week, but Mr @riban has started a new round of refactorization + adding features + rethinking everything, what is really good. I can’t say no to improving the fun!!

So, i’m testing and testing …

Do you want a litle :face_with_monocle: ? OK …

BTW, do you know that stepseq is integrated with snapshots? We can now share the full project for a piece:

010-JV;Obxd;002-KVR_Bass;Legion.zss (31.2 KB)

Of course, you have to try this snapshot on the feature/stepseq branch …

Enjoy!

8 Likes

OK! Another one. Just jamming, nothing special …

And the snapshot, of course:

009-ZY;Noises;Metal Sound 2.zss (41.3 KB)

5 Likes