Sammy1Am / MoppyClassic

Moppy has been replaced with Moppy 2.0!
568 stars 191 forks source link

More drives for Arduino Mega and/or live MIDI playback? #5

Closed ggppjj closed 9 years ago

ggppjj commented 12 years ago

I have an Arduino Mega 2560, and I was wondering if it were possible to expand the capabilities of Moppydesk and the Arduino code for 10 or more drives and/or playing MIDI input from instrument controllers. I was wondering this mainly because of the potential to play full piano pieces using an electronic piano and being limited to only eight notes at once. I myself cannot play piano, nor do I even have an electronic piano, but I know people who do, and can. It would be nice, I think, to add more drives, and maybe offer the option to mesh the notes instead of dedicated drives per tracks. It would offer the potential for faster pieces, and less wear on individual drives.

Sammy1Am commented 12 years ago

So first off, it's definitely possible to extend the Arduino code for an Arduino Mega to use up to 16 drives. 16 is the limit for the current design since each drive gets its own MIDI channel, and 16 is the most MIDI channels the specification supports (though for piano purposes, 10 would probably be plenty given most peoples' limit of a maximum of 10 fingers, lol). An Arduino Uno, in fact, should support up to 9 drives.

In terms of playing live piano pieces using the piano, I've actually played around with some code to do that using my current 8 drives. The MIDI keyboard is connected to my PC and the Java software distributes notes as they are played (the keyboard inputs notes on only a single MIDI channel) to the various floppy drives to make sure all the notes can be played. Unfortunately, I can't play piano at all, so I haven't really had a chance to explore this too thoroughly. I do plan on eventually incorporating that code into the current code base, but haven't had time to clean it up and remove some of the hard-coded variables.

Distribution of the notes is an interesting problem in itself. Since I didn't spend much time, I basically just assigned notes to the first available drive in an array of drives. This means that drive #1 is pretty much constantly playing though, and that drive #8 rarely gets any notes. I've considered assigning each drive a range on the keyboard, so that in general notes would be spread among them, but that requires a somewhat more complex sharing algorithm for when multiple notes show up in the same 1/8th of the keyboard. Another straight-forward method would be to assign notes to drives in a round-robin fashion. This would be very effective at leveling the wear on the drives, but unless the drives are all identical might mean that notes randomly change timbre, and I might sound kind of weird with the notes appearing in different physical locations each time.

If you're looking to do the modifications yourself, I can point you to the following locations in the Arduino code to add extra drives:

In the Java code there's a variable for the number of drives, just increase that to whatever you've added.

If you want to implement the live piano playback and drive-sharing, you're on your own for now. Though if you have specific questions I can try to help. I'll get around to incorporating those features eventually, but it might be a while.

While I'm on the topic, there's another interesting idea that's more or less the inverse of the piano's single-channel to many-channels logic. It should be possible to read all of the input channels from a MIDI file, and assign notes to drives as they come in (sort of a many-to-many logic). Each drive wouldn't get its own channel, but this would make it possible to play arbitrary MIDI files without having to arrange for the drives specifically. All three logics would operate with the same Arduino code though, so it should be possible to have like a mode-selection switch in the Java code to switch between them.

I'll leave this issue open for now in case anyone has additional ideas or wants to try their hand at making some of these modifications.

Edit: The Arduino Uno can only support up to 9 drives. Thanks, TopFuelProductions

ggppjj commented 12 years ago

I forked and edited both the Java and Arduino codes. I think I did it right, but I've had very little experience with both, so I'm not sure. I just edited based on your code comments, and the existing code. I would appreciate it if you would try it on your Uno, to see if it'll work without the maximum pins. I verified it using both the Mega and Uno settings on the compiler, but I don't know if that means it'll work on both as such. I also ran the Java code successfully, but I haven't tested the new, 16 channels yet. I plan on soon, though ;-P

Sammy1Am commented 12 years ago

Excellent, it looks good! I'll test it on my 8-drive set-up first (to make sure the extra pins don't cause any issues) before pulling the changes over. My only other concern would be that there might be performance issues for running through twice as many checks each time around, but I suppose if that's the case, it's not hard to comment out those parts on a case-by-case basis.

I'm trying to think if there's a convenient way to offer different code for those who want to use less drives (e.g. they want to use the additional pins to do something else), but I suppose if they're planning on using the other pins, they'll need to modify the code anyway, and they can just deal with it then.

Thanks for your help!

ggppjj commented 12 years ago

I'd be glad to do the edits for different boards, and have the Arduino folder filled with board/drive specific configurations. Shouldn't be too hard, just a tiny bit time-consuming. I'm not sure if the Java program would need edits for each individual configuration, though. If it does, again: Simple, but tedious. I'm up for it, though.

Sammy1Am commented 12 years ago

Yeah, sorry for not having tested it yet; busy, busy.

If the Java program needed to be different for each board, it might be easier to put in a little drop-down menu. I don't think at this point there's any modifications needed to the Java code though (it'll send channels 1-16 to the Arduino regardless of what the Arduino is expecting). In the future the code might need to be configured so it knows how many drives are present (for drive-sharing with live-playback and such).

If you do make an edit for a specific board as a separate file, put in a pull-request (or however that works, I'm still new to github) and I'll have no problem incorporating that. I'd just want to test any changes to the current file to make sure it doesn't break on Unos.

paintjob commented 12 years ago

I just started playing with this code about a week ago, and I've come up with the same ideas. :D I just picked up a midi keyboard controller today and was thinking about mapping some floppy drives to an Arduino Mega to "play them live."

I also have the midi shield from sparkfun that I plan on incorporating to my project. I'm new to java programming, but I am pretty familiar with C++/Arduino. Would it be worth it to try and move large chunks of this code into it's own library? That way you can set the number of drives used and the pins you're connected to when you call an instance of the "Moppy class?"

I've created a custom interface board and some custom cat5/idc cables for my drives and I plan on connecting to the pins in the area of 22-53 on the Mega because of the shield I have on top. That's why I was thinking of making it easier to modify which pins the drives are connected to.

I've forked the code as well and plan on working towards these ends.

Sammy1Am commented 12 years ago

A library is actually an excellent idea, because like you said, it would make a lot easier to integrate this code with other configurations and boards. Along those lines, perhaps if the number and location of pins is configurable somehow, that'll alleviate the need for others like ggppjj to create different builds for each board.

Let me know if there's anything I can do to help toward that end. I'd offer to start working on it myself, but I wouldn't want to need to deal with merging, and to be honest I probably will not have time to really get into it much anytime soon.

minihui commented 12 years ago

Hi SammyIAm your Moppy is super sweet! I've managed to tweak your java code a little bit to achieve live MIDI input and I would like to share it. It should accept any MIDI physical devices, and with IAC driver on a Mac or a 3rd party MIDI loopback driver, it should take care of MIDI output from audio software. It's confirmed working on my Mac running Pro Tool 10.

Sammy1Am commented 12 years ago

I would love to merge that code into the current code for everyone to play with. The best way to get it in here is probably go through the normal github... pull request... something... This is my first time using github, so I'm learning everything as I go. That way it'll be clear that you contributed the code so you get credit, but it should be a little cleaner too.

If that's not feasible, you can just email me the code (if you want to send me a direct message to @Sammy1Am on twitter, I'll send you my email; just let me know it's you). It might be a little while 'til I get it rolled in (Diablo 3! Woo!) but I'm definitely looking forward to having support for that.

Thanks!

minihui commented 12 years ago

ok, I'll try the request stuff first. Actually this is my first time using GitHub, NetBeans, Java, and even Arduino so if I can't make it work I'll do the second way.

mamarley commented 12 years ago

Something you might run into trying to run lots of drives is performance problems. I have done quite a bit of playing around with the Arduino code and have found that in some cases (like if you are playing the 279BPM nyancat song on 8 drives) the Arduino simply cannot keep up and will stop working. (The timer interrupt fires before the last timer interrupt handler finishes, causing the Arduino to "lock". The current note(s) keep(s) playing, but there is no response to serial communication.)

In order to solve this problem, I made some major modifications to the Arduino code to make it use AVR port assignments instead of the Arduino digitalWrite() function. The code is extremely efficient and allows for playing the above-mentioned nyancat song on 8 drives with 20us resolution without problems. However, much of the tick() function is hardcoded now and it isn't nearly as elegant as before. Also, the code pretty much requires an ATMega168 or 328-based board, such as a Duemilanove or Uno. It could be made to work on another board, but that would require changing all the port assignments. The general idea might be useful if you wanted great performance with 16 drives on a Mega.

If you want to try it, you can get it from my fork here: https://github.com/mamarley/Moppy

Also, I have modified the both the Java code and the Arduino code to use a higher resolution (20us) and a higher serial rate (115200), so an Arduino running my fork will not be compatible with the original Java program and vice-versa.

yoko8332 commented 10 years ago

Hello. I wanna ask something myself. I managed to play the samples of the projects on my floppy. But as i see the midis i download dont manage to play. So can i find some place to download some right midis

tg44 commented 10 years ago

Nowhere. I figured it out too. If you have some java skill you coud try to use this: https://github.com/tg44/MidiSplitter This need an input and an output filename (as prameter). Try using flstudio or other graphical midi tool to see what generated. The Splitter is a good starting point, but it need a lot of work if u want to use it in highend "justsomeclick" transformations... It can create some splitted no chords multichannel things. I pushed up some bugfixes what i do 2 days ago, now its working perfectly (but need a good graphical interface and a big refactor :) ).

daimoniac commented 10 years ago

you can find many midi's for floppy playback here: https://github.com/coon42/Floppy-Music--midis-

kg7rdr commented 9 years ago

Has anyone successfully gotten a fork for live midi. I have an idea of using MIDI-OX and MIDI-Yoke to drop some channels down an octave. A midi player (midibar) will play the midi file to a midi-yoke virtual midi port. Through midi-ox port mapper I can drop certain channels where I want, then output everything to a midi output physical or virtual. My problem now is that Moppy won't accept any midi-in from windows7. It simply seems as if realtime midi input functionality has not been added to find a list of midi devices.

Sammy1Am commented 9 years ago

The Moppy Advanced branch (now the default branch) in my repo supports realtime MIDI input. You should just be able to choose the correct "Input Mode" option, and choose the appropriate MIDI IN port. I've successfully tested it with a physical MIDI device (keyboard) as well as using a virtual device (hooked up Sibelius directly to the drives).

kg7rdr commented 9 years ago

The only option on the dropdown is "Real Time Sequencer" I have tried on 64 and 32 bit JDK to match the 32 bit midi software, but still the same results.

I have been working on making a more pleasing and colorful UI for moppy. and I may have ruined some code somewhere, I am going to get the repo from here and try it again.

Sammy1Am commented 9 years ago

You'll have to forgive me for not remembering exactly what the UI looks like; it's been rather a long time since I've used the application myself. Real Time Sequencer should be what you're looking for, and there should be an additional menu (or something) that gives you choices of MIDI IN ports.

Since it works fine for me, I unfortunately can't help debug your issue too much. Check the NetBeans output to see if there are any error messages. Otherwise, you might try running another Java MIDI program to see if it can find your devices (just to see if it's an issue with Moppy or Java in general on your machine). Also make sure you're using the correct type of port (IN versus OUT); the naming convention can be confusing at times.

kg7rdr commented 9 years ago

The UI looks like windows 95 retro style. I am trying to get it working with windows aero. About real time sequencer, there is no additional menu that opens. The java does not seem to point to anything. Netbeans only shows four errors that the comment format wil not be supported in the next version of java, so nothing important. I have just switched to another machine(my audio production desktop). Physical keyboard midi is connected, but does not show up in the MIDI-IN port dialogue box. I am starting to wonder If this is a problem with the java8 32/64 bit. Moppy might be trying to run at a higher level 64 bit and not starting the 32 bit jvm.

What version of java did you use?

Thank you. I appreciate devs who respond to their work, no matter how old. Your response surprises me and is a sign of your support

Sammy1Am commented 9 years ago

I believe when you choose "Real Time Sequencer", it's supposed to replace the sequencer controls (play, pause, tempo) with a drop down menu that shows available MIDI IN devices. If the UI isn't changing, there may be an issue in the code somewhere.

If it is changing, but you don't see the device in the menu, then Java isn't seeing the device. It very well may be a Java version issue.

I tested using Windows 7 and 64-bit Java 7 (I'm pretty sure-- might have been 6 though).

kg7rdr commented 9 years ago

Ok, I was not sure if there was an additional menu. That menu is not appearing. Time for debunking and finding the code. That just might be the reason I cannot see the midi device.

kg7rdr commented 9 years ago

It was java. The rxtx libraries were opening in a 64 bit jvm and moppy was running on 64 bit netbeans, but the code was pointed to an obsolete jdk7 32 bit. If you get all of the libraries and the environment to 32 bit, the application works fine. if it is in 64bit, none of my 64bit midi applications would show. Someday when I am less lazy, I plan to bring the applications and moppy to a unified 64-bit

Thank You Sammy