MT-PowerDrumKit Alternative ?
Moderators: MattKingUSA, khz
MT-PowerDrumKit Alternative ?
Hi,
I'm looking for an alternative to MT-PowerDrumKit, which is both a drumkit emulator and a pattern sequencer, freeware for Ms Windows (and a brilliant and simple one). I know I could run it through Wine/Carla but an open source, native solution would be preferred.
The drumkit emulator part is totally doable in lots of ways (soundfonts, or my favorite, Drumgizmo). The pattern sequencer, though, is hard to emulate.
I already have a bank of midi patterns (extracted from MT-PowerDrumKit's exe resources) , now I need to be able to sequence them.
I think I've tried every Github & Sourceforge midi app to do it, with no success. The closest I've emulated it was with the always good Hydrogen, by converting my midi patterns to H2's own format (thanks to Domino Marama's m2hps, http://dominodesigns.info/m2hpc/index.html), but :
1) it lacks preview, you have to import the pattern in the editor to hear it
2) the library cannot be sorted, nor directories created (I have over 9000 patterns)
3) the patterns cannot be imported on the same track, each import creates its own one
4) to the best of my knowledge, it cannot directly handle a reference track, unless syncing it with a DAW playing said reference track.
Has anyone got an idea ? Thanks in advance,
- Hw
I'm looking for an alternative to MT-PowerDrumKit, which is both a drumkit emulator and a pattern sequencer, freeware for Ms Windows (and a brilliant and simple one). I know I could run it through Wine/Carla but an open source, native solution would be preferred.
The drumkit emulator part is totally doable in lots of ways (soundfonts, or my favorite, Drumgizmo). The pattern sequencer, though, is hard to emulate.
I already have a bank of midi patterns (extracted from MT-PowerDrumKit's exe resources) , now I need to be able to sequence them.
I think I've tried every Github & Sourceforge midi app to do it, with no success. The closest I've emulated it was with the always good Hydrogen, by converting my midi patterns to H2's own format (thanks to Domino Marama's m2hps, http://dominodesigns.info/m2hpc/index.html), but :
1) it lacks preview, you have to import the pattern in the editor to hear it
2) the library cannot be sorted, nor directories created (I have over 9000 patterns)
3) the patterns cannot be imported on the same track, each import creates its own one
4) to the best of my knowledge, it cannot directly handle a reference track, unless syncing it with a DAW playing said reference track.
Has anyone got an idea ? Thanks in advance,
- Hw
Re: MT-PowerDrumKit Alternative ?
Hi,
Well, nothing fancy, just a resources extractor and a little dumb homemade script to split the biggest file into its smaller parts.
Well, nothing fancy, just a resources extractor and a little dumb homemade script to split the biggest file into its smaller parts.
Re: MT-PowerDrumKit Alternative ?
Hi,
I wrote a simple ruby-script that extracts the MIDI-Files:
Just use it like:
and everything will be in ./midi.
Regards,
Jochen
I wrote a simple ruby-script that extracts the MIDI-Files:
Code: Select all
#encoding: utf-8
require 'rexml/document'
require 'fileutils'
dll = ARGV[0]
dest = ARGV[1]
data= IO.read('MT-PowerDrumKit.dll', :encoding=>'ascii-8bit')
xml_start = data.index('<GrooveDef')
xml_end = data.index('</GrooveDef>')+'</GrooveDef>'.length
xml = data[xml_start..xml_end]
data_start = xml_end+2
doc = REXML::Document.new(xml)
root = doc.root
root.elements.each("SuperStyle") do |ss|
ss.elements.each("Style") do |s|
s.elements.each("Groove") do |g|
n_g = g.attributes["Name"].gsub("/","_")
path = File.join([dest] + [ss, s, g].map{|e| e.attributes["Name"].gsub("/","_")})
FileUtils.mkdir_p(path)
offset = g.attributes["Offset"].to_i
size = g.attributes["Size"].to_i
File.open(File.join(path, n_g)+".mid","w"){|fil| fil.write(data[data_start+offset, size])}
g.elements.each("Fill") do |f|
n_f = f.attributes["Name"].gsub("/","_")
offset = f.attributes["Offset"].to_i
size = f.attributes["Size"].to_i
File.open(File.join(path, n_f)+".mid","w"){|fil| fil.write(data[data_start+offset, size])}
end
end
end
end
Just use it like:
Code: Select all
ruby extract.rb ./MT-PowerDrumKit.dll ./midi
Regards,
Jochen
Last edited by jochen on Tue May 17, 2016 5:19 am, edited 1 time in total.
Re: MT-PowerDrumKit Alternative ?
Hi,
Mine was in php and worked after the files were extracted from the exe, but its pretty close
So I hope it helps someone out there, but doesn't help me. Has anyone got a clue how to sequence these extracted midi files ?
Regards,
Hw
Mine was in php and worked after the files were extracted from the exe, but its pretty close
So I hope it helps someone out there, but doesn't help me. Has anyone got a clue how to sequence these extracted midi files ?
Regards,
Hw
Re: MT-PowerDrumKit Alternative ?
Hi Hw,
to sequence the extracted grooves and fills I wrote another ruby script. Use it like
Always add parameters in pairs: midi-file + how many bars you want to use from it.
The last parameter is the output filename.
To playback the resulting file I use:
to sequence the extracted grooves and fills I wrote another ruby script. Use it like
Code: Select all
ruby seq.rb groove01.mid 3 fill01.mid 1 groove02.mid 3 fill02.mid 1 output.mid
The last parameter is the output filename.
To playback the resulting file I use:
Code: Select all
jack-smf-player -t -a MT-PowerDrumKit:events-in test.mid
Code: Select all
#encoding: utf-8
class Event
attr_reader :dtime, :data, :type, :note
def initialize(dtime, data, type, note=nil)
@dtime = dtime
@data = data
@type = type
@note = note
end
def dtime=(val)
buffer = []
buffer << (val & 0x7f)
val = (val >> 7)
while val > 0
buffer << (0x80 + (val & 0x7f))
val = (val >> 7)
end
@data.shift while (@data[0]&0x80).nonzero?
@data.shift
buffer.each{|b| @data.unshift(b)}
end
def self.eot
self.new(dtime = 0, data = [0x00, 0xff, 0x2f,0x00], :eot)
end
end
class SMF
attr_reader :events, :data, :tr_len, :len, :eob
def initialize(file)
@data = IO.read(file,:mode=>'rb', :encoding=>'ascii-8bit')
parse
@eob = @len
end
def getb
return nil if @data.length <= @data_pos
b = @data.bytes[@data_pos]
@data_pos+=1
b
end
def bars(n)
tmp = []
time = 0
@eob = (n*@numer.to_f/2**@denom*4*@hd_dtt).to_i
@events.each do |e|
if (time + e.dtime) < @eob
tmp << e
time += e.dtime
else
break
end
end
@events = tmp
@len = time
end
def append(smf)
d = @eob - @len
warn "d: #{d}"
smf.events.first.dtime = d
@events.concat(smf.events)
@len = @eob + smf.len
@eob += smf.eob
end
def save_as(fn)
es = @events.dup
es << Event.eot
edata = es.map{|e| e.data.map{|d| d.chr}.join}.join
mid = @data[0,18] + [edata.length].pack("N") + edata
File.open(fn,"wb"){|f| f.write(mid)}
end
def parse
@hd_id = @data[0,4]
@hd_len = @data[4,4].unpack("N")[0]
@hd_fmt = @data[8,2].unpack("n")[0]
@hd_n = @data[10,2].unpack("n")[0]
@hd_dtt = @data[12,2].unpack("n")[0]
@tr_id = @data[14,4]
@tr_len = @data[18,4].unpack("N")
@data_pos = 22
state = :wait_start
time = []
cmd = nil
meta_cmd = nil
val = 0
txt_len = nil
txt = ""
b = ""
@len = 0
ev_data = []
@events = []
while b = getb do
case state
when :wait_start
ev_data << b
if (b&0x80).nonzero?
time << (b&0x7f)
else
time << b
val = 0
time.each do |v|
val = (val << 7) + v
end
@len += val
time = []
state = :wait_cmd
end
when :wait_cmd
ev_data << b
cmd = b
if cmd == 0xFF
state = :wait_meta_cmd
elsif (cmd&0x90).nonzero?
note = getb
vel = getb
ev_data << note
ev_data << vel
@events << Event.new(val, ev_data.dup,:note_on, note)
ev_data = []
state = :wait_start
else
raise "unknown cmd: #{b.to_s(16)} (#{@data_pos})"
end
when :wait_meta_cmd
meta_cnd = b
ev_data << b
if b == 0x03
state = :wait_text_length
elsif b == 0x58
t = []
t << getb #len
t << @numer = getb
t << @denom = getb
t << getb #tpb
t << getb #32pb
ev_data.concat(t)
@events << Event.new(val, ev_data.dup, :time_sig)
ev_data = []
state = :wait_start
elsif b == 0x2f # end of track
getb # 0
ev_data = []
state = :wait_start
else
raise "unknown meta cmd: #{b.to_s(16)}"
end
when :wait_text_length
txt_len = b
ev_data << b
state = :wait_text
when :wait_text
txt << b
ev_data << b
if txt_len > 1
txt_len -= 1
else
state = :wait_start
@events << Event.new(val, ev_data.dup, :txt)
ev_data = []
end
end
end
end
end
if __FILE__==$0
output = ARGV.pop
midis = []
(1..ARGV.length).step(2) do |i|
n = ARGV[i].to_i
smf = SMF.new(ARGV[i-1])
smf.bars(n)
midis << smf
end
first = midis.shift
midis.each { |m| first.append(m) }
first.save_as(output)
end
Re: MT-PowerDrumKit Alternative ?
Hi again,
@Jochen, Thanks for the script ! Not what I'm asking for but definitely a great tool. Though, you are probably in my exact position, having thousands of drum loops, choosing one is the most complex part. You seem to be quite fluent in ruby, any way you think you could create a program with a GUI, that allows to browse our collection of midis and set them in place, with an easy "listen on hover/single click" ?
@Beck, Good tip ! LMMS has a better browser than Hydrogen. It suffer 3 main drawbacks for my intended use though :
1) doesnt preview on hover or single click : I have to import the midi to hear it
2) each imported part is put on its own track (with a soundfont player), and cannot be directly dragged in place on a track where the midi channel of the soundfont is already set to drums.
3) I haven't found the way to export midi from a track, to import in Ardour.
Maybe some LMMS guru could help us ?
@Jochen, Thanks for the script ! Not what I'm asking for but definitely a great tool. Though, you are probably in my exact position, having thousands of drum loops, choosing one is the most complex part. You seem to be quite fluent in ruby, any way you think you could create a program with a GUI, that allows to browse our collection of midis and set them in place, with an easy "listen on hover/single click" ?
@Beck, Good tip ! LMMS has a better browser than Hydrogen. It suffer 3 main drawbacks for my intended use though :
1) doesnt preview on hover or single click : I have to import the midi to hear it
2) each imported part is put on its own track (with a soundfont player), and cannot be directly dragged in place on a track where the midi channel of the soundfont is already set to drums.
3) I haven't found the way to export midi from a track, to import in Ardour.
Maybe some LMMS guru could help us ?
Re: MT-PowerDrumKit Alternative ?
Hi Beck,
Regarding the 3 points mentioned,
The 1st point would be enough to make it a practical solution, so I hope its feasible and someone with the know-how will chime in
2) copy pasting with ctrl+click works, but in my use case, it's very uncomfortable as it creates as many new tracks as I've imported sequences
3) I want to import the midi in Ardour (not the audio), to be able to use e.g. Drumgizmo to synth the drum hits. LMMS has a built-in export feature for audio, but AFAICT no midi export (seems to be part of the upcoming 1.2 version though).
Thanks for the ideas !
Regarding the 3 points mentioned,
The 1st point would be enough to make it a practical solution, so I hope its feasible and someone with the know-how will chime in
2) copy pasting with ctrl+click works, but in my use case, it's very uncomfortable as it creates as many new tracks as I've imported sequences
3) I want to import the midi in Ardour (not the audio), to be able to use e.g. Drumgizmo to synth the drum hits. LMMS has a built-in export feature for audio, but AFAICT no midi export (seems to be part of the upcoming 1.2 version though).
Thanks for the ideas !
Re: MT-PowerDrumKit Alternative ?
For me, the biggest problem of using MT-PowerDrumKit under Linux was that dragging and dropping of the sequence to Qtractor, Ardour, etc. does not work.
Now I wrote a simple application that reads the grooves from the DLL and lets you browse, preview and sequence them. Then the sequence can be saved to a file or directly be dragged and dropped to Qtractor or Ardour.
* Preview of a groove is initiated by a double click.
* Use the Add-button or simple drag and drop a groove to the sequence list.
* the Play-button starts playback of the sequence.
* Export saves the sequence to a file of your choice.
* Drag the Export-button to Qtractor or Ardour to have the sequence there.
Dependencies:
* ruby
* Active Support (gem install activesupport)
* qtbindings (gem install qtbindings)
If you want to try it, you have to modify config.rb (path to dll, playback command).
run it with:
Now I wrote a simple application that reads the grooves from the DLL and lets you browse, preview and sequence them. Then the sequence can be saved to a file or directly be dragged and dropped to Qtractor or Ardour.
* Preview of a groove is initiated by a double click.
* Use the Add-button or simple drag and drop a groove to the sequence list.
* the Play-button starts playback of the sequence.
* Export saves the sequence to a file of your choice.
* Drag the Export-button to Qtractor or Ardour to have the sequence there.
Dependencies:
* ruby
* Active Support (gem install activesupport)
* qtbindings (gem install qtbindings)
If you want to try it, you have to modify config.rb (path to dll, playback command).
run it with:
Code: Select all
ruby sequencer.rb
- Attachments
-
- sequencer.tar.gz
- (4.83 KiB) Downloaded 134 times
Re: MT-PowerDrumKit Alternative ?
Hi jochen, and thanks for your hard work !
For those wanting to install your sequencer, here's how I did based on error messages :
downloading Jack-smf-utils (https://sourceforge.net/projects/jack-smf-utils/)
uncompressing it in a folder, then in that folder,
I've also copied the MT-PowerDrumKit.dll and MT-PowerDrumKit-Content.pdk in the directory where I put Sequencer, and edited the config.rb file to :
I have a few problems though :
1) Clicking on a rythm gets no sound out, the console reads :
2) Clicking the "play" button results in a crash :
3) Clicking the "export" button lets me select a file name, then crashes the app with the same error message seen in (2)
4) I got random crashes on clicking the left treeview :
I hope my report is meaningful to you more than it is to me, this app would be very useful !
Regards, (and again, thanks for your hard work)
Hw
For those wanting to install your sequencer, here's how I did based on error messages :
Code: Select all
sudo apt-get install ruby
sudo apt-get install ruby1.9.1-dev
sudo apt-get install cmake
sudo apt-get install qt-sdk
sudo gem install activesupport
sudo gem install qtbindings
uncompressing it in a folder, then in that folder,
Code: Select all
./configure
make
sudo make install
Code: Select all
module SeqConfig
PLAY_CMD = "jack-smf-player -t -a MT-PowerDrumKit:events-in"
KILL_CMD = "killall jack-smf-player"
DLL = "MT-PowerDrumKit.dll"
end
1) Clicking on a rythm gets no sound out, the console reads :
Code: Select all
jack-smf-player: aucun processus trouvé
jack-smf-player: format: 0 (single track); number of tracks: 1; division: 480 PPQN.
jack-smf-player: format: 0 (single track); number of tracks: 1; division: 480 PPQN.
jack-smf-player: Cannot connect to MT-PowerDrumKit:events-in.
jack-smf-player: Couldn't connect to 'MT-PowerDrumKit:events-in', exiting.
Code: Select all
(myhomepath)/Téléchargements/sequencer/smf.rb:49:in `getb': undefined method `[]' for #<Enumerator:0x000000030a7f00> (NoMethodError)
from /home/edouard/Téléchargements/sequencer/smf.rb:115:in `parse'
from /home/edouard/Téléchargements/sequencer/smf.rb:42:in `initialize'
from /home/edouard/Téléchargements/sequencer/pdk.rb:36:in `new'
from /home/edouard/Téléchargements/sequencer/pdk.rb:36:in `block in write_seq'
from /home/edouard/Téléchargements/sequencer/pdk.rb:35:in `each'
from /home/edouard/Téléchargements/sequencer/pdk.rb:35:in `write_seq'
from /home/edouard/Téléchargements/sequencer/pdk.rb:55:in `play_seq'
from sequencer.rb:202:in `playSeq'
from /var/lib/gems/1.9.1/gems/qtbindings-4.8.6.2/lib/Qt/qtruby4.rb:479:in `qt_metacall'
from /var/lib/gems/1.9.1/gems/qtbindings-4.8.6.2/lib/Qt/qtruby4.rb:479:in `method_missing'
from /var/lib/gems/1.9.1/gems/qtbindings-4.8.6.2/lib/Qt/qtruby4.rb:479:in `exec'
from sequencer.rb:298:in `<main>'
4) I got random crashes on clicking the left treeview :
Code: Select all
sequencer.rb:72:in `&': can't convert Qt::Enum into Integer (TypeError)
from sequencer.rb:72:in `mouseMoveEvent'
from /var/lib/gems/1.9.1/gems/qtbindings-4.8.6.2/lib/Qt/qtruby4.rb:479:in `method_missing'
from /var/lib/gems/1.9.1/gems/qtbindings-4.8.6.2/lib/Qt/qtruby4.rb:479:in `exec'
from sequencer.rb:298:in `<main>'
Regards, (and again, thanks for your hard work)
Hw
Re: MT-PowerDrumKit Alternative ?
Hello Hw,
1) in
the parameter "-a MT-PowerDrumKit:events-in" means, jack-smf-player should send the midi data to the jack-midi-port "MT-PowerDrumKit:events-in". If you got MT-PowerDrumKit running through carla, this port should be available. But of course you can choose to use another port that belongs to another application..
2,3,4) You are using ruby 1.9.1 while i developed with ruby>=2.0.0. I wonder how you could install qtbindings with 1.9.1? If I try to install it with 1.9.2 I get
I modified the commands that gave you the errors so that they should also work with 1.9.1, but as I can't install qtbindings I can't test it... there may be other problems...
Can you install a newer ruby (>=2.0.0)? That would be better.
regards,
Jochen
1) in
Code: Select all
PLAY_CMD = "jack-smf-player -t -a MT-PowerDrumKit:events-in"
2,3,4) You are using ruby 1.9.1 while i developed with ruby>=2.0.0. I wonder how you could install qtbindings with 1.9.1? If I try to install it with 1.9.2 I get
Code: Select all
ERROR: Error installing qtbindings:
qtbindings requires Ruby version >= 2.0.0.
Can you install a newer ruby (>=2.0.0)? That would be better.
regards,
Jochen
- Attachments
-
- sequencer.tar.gz
- (5.08 KiB) Downloaded 127 times
Re: MT-PowerDrumKit Alternative ?
SUCCEEEESSS !!!
Thanks for having modified your script.
Remember my OP : I wanted no wine in my config.
So, following your advice, I changed the config's playback function to :
Lanched Qsynth, opened the fluidR3_GM.sf2 soundfont, changed the channel/bank to 128/0
I works ! I can now enjoy your script and create drumlines ! No need for MT-PowerDrumKit's except for the midi resources
Thanks a lot !
BTW, I didn't change my ruby version, so I'm still <2.
Thanks for having modified your script.
Remember my OP : I wanted no wine in my config.
So, following your advice, I changed the config's playback function to :
Code: Select all
PLAY_CMD = "jack-smf-player -t -a qsynth:midi"
I works ! I can now enjoy your script and create drumlines ! No need for MT-PowerDrumKit's except for the midi resources
Thanks a lot !
BTW, I didn't change my ruby version, so I'm still <2.
-
- Established Member
- Posts: 2059
- Joined: Tue Feb 16, 2016 6:56 am
- Location: Kangasala, Finland
- Has thanked: 375 times
- Been thanked: 209 times
- Contact:
Re: MT-PowerDrumKit Alternative ?
Wanted to try this, but unfortunately 'gem install qtbindings' fails. Running ubuntu 16.04. From error log:jochen wrote:Now I wrote a simple application that reads the grooves from the DLL and lets you browse, preview and sequence them. Then the sequence can be saved to a file or directly be dragged and dropped to Qtractor or Ardour.
...
Dependencies:
* ruby
* Active Support (gem install activesupport)
* qtbindings (gem install qtbindings)
I'm not familiar with ruby & gems, but I know that there is no library pthreads but it is pthread./usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_61ec7.dir/CheckFunctionExists.c.o -c /usr/share/cmake-3.5/Modules/CheckFunctionExists.c
Linking C executable cmTC_61ec7
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_61ec7.dir/link.txt --verbose=1
/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create CMakeFiles/cmTC_61ec7.dir/CheckFunctionExists.c.o -o cmTC_61ec7 -rdynamic -lpthreads
/usr/bin/ld: cannot find -lpthreads
collect2: error: ld returned 1 exit status
Linux veteran & Novice musician
Latest track: https://www.youtube.com/watch?v=ycVrgGtrBmM
-
- Established Member
- Posts: 2059
- Joined: Tue Feb 16, 2016 6:56 am
- Location: Kangasala, Finland
- Has thanked: 375 times
- Been thanked: 209 times
- Contact:
Re: MT-PowerDrumKit Alternative ?
Got back to this. Got ruby gems installed, build error messges were confusing me when I was too tired. Actual problem was ruby-dev package missing.
I wanted drums to be played from hydrogen, so I used pmidi instead of jack-smf-player.
Edit: in hydgen midi options selecting 'ignore note-off' will fix issue!
Edit2: and hydrogen has also jack-midi option, so it would be possible to use jack-smf-player also
I wanted drums to be played from hydrogen, so I used pmidi instead of jack-smf-player.
And from that I could get port to connect. To config.rb:pmidi -l # to list ports
I got it playing, but does not sound very good. It sounds like all drum samples play short, maybe getting note off soon after note on, and hydrogen honoring those note off commands?PLAY_CMD = "pmidi -p 129:0"
Edit: in hydgen midi options selecting 'ignore note-off' will fix issue!
Edit2: and hydrogen has also jack-midi option, so it would be possible to use jack-smf-player also
Linux veteran & Novice musician
Latest track: https://www.youtube.com/watch?v=ycVrgGtrBmM
-
- Established Member
- Posts: 2059
- Joined: Tue Feb 16, 2016 6:56 am
- Location: Kangasala, Finland
- Has thanked: 375 times
- Been thanked: 209 times
- Contact:
Re: MT-PowerDrumKit Alternative ?
This is really great!jochen wrote: Now I wrote a simple application that reads the grooves from the DLL and lets you browse, preview and sequence them. Then the sequence can be saved to a file or directly be dragged and dropped to Qtractor or Ardour.
* Preview of a groove is initiated by a double click.
* Use the Add-button or simple drag and drop a groove to the sequence list.
* the Play-button starts playback of the sequence.
* Export saves the sequence to a file of your choice.
* Drag the Export-button to Qtractor or Ardour to have the sequence there.
One additional feature would be great: setting tempo. Now everything plays on 120 BPM, and if looking for suitable beat for something really different, spotting the one you want is not trivial.
So what would be needed:
- text field for inputting tempo
- calculate 60000000/BPM
- if there is some ruby lib for modifying midi file, then use that, but if not, it can be done with smfsh:
smfsh> load input.mid
smfsh> add 0 ff51030ac55a
smfsh> save output.mid
In example I had tempo 85, which will result in hex 0AC55A. Tempomap event is ff5103.
Edit: https://github.com/jimm/midilib
Linux veteran & Novice musician
Latest track: https://www.youtube.com/watch?v=ycVrgGtrBmM