Build Thread - Beatmaker

Status
Not open for further replies.
My dearest brother came through for christmas!" :)

FullSizeRender.jpg

Much breadboarding then wiring to be done. :)

Software is taking baby steps but inching forwards. Capability is looking fairly good, sounds great in 44Khz RAW mono.
 
It's been a busy christmas :)

LCD up and running, and all buttons connected via PS/2 Mini pac interface.

All sixteen buttons on the right triggering RAW samples and it sounds awesome, feels great to play.

Only bug I've found is when you press multiple buttons together I get funny codes from the PS/2 input once in a while - might be due to CPU cycles running low, as this requires 3 or 4 samples to trigger all at once which is nigh-on maxing out the cpu. When i tested the device on the PC it correctly handled multiple buttons presses, but that was via USB. I'm now running through a PS/2 adapter so the MINIPAC is also running in PS/2 mode. Might be a bug here but since its used to build arcade cabinets (multiple buttons at once are more than common), i doubt it.

FullSizeRender (1).jpg
 
Last edited:
Yes.

But it is a big undertaking so I went for the easiest robust method. My time is expensive :)
 
I have a spare teensy so I've got a fallback. Once I've implemented RAW from flash, it should be a healthier environment for the PS/2 interrupt needs.
 
Blast. The P/s2 library description implies that it supports key up and key down strokes but it will need a fairly significant rewrite to handle this. :-(

Probably easier to use my spare Teensy, tbh. How do I send commands between teensy's? Is there an example I can look at somewhere?
 
Blast. The P/s2 library description implies that it supports key up and key down strokes but it will need a fairly significant rewrite to handle this. :-(

I've got a few options

1) connect the other 16 inputs on the minipac to the normally closed pins on the arcade buttons. This uses 32 inptus for 16 buttons, doubles the PS/2 traffic overhead unnecessarily and leaves me with 16 orphaned buttons to connect up somehow (might have a couple of spare pins to use for resistor arrays, or some kind of interleaving chip)

2) Add a Teensy and use i2C to pull in its pins; I will _just_ get 32 pins this way. This is my "last resort" as I am concerned about latency over i2c.

3) Author a new leaner version of the PS2Keyboard library specifically for the mini-pac which uses less ram but supports KEYUP and KEYDOWN events. There are only 32 inputs so we can reduce the RAM footprint by eliminating unnecessary char codes and conversion. I only need to know keyup and key down for 32 specific keys.

Think i'll have a crack at 3), everything i need is already there, the scan codes are pulled in, i just need to interpret them differently.
 
Well it was a lot easier than i thought, once i'd finally got my head around the code.

i just commented out two lines in get_iso8559_char, 1 of which wiped the BREAK flag too early, and one of which blocked keyup chars from being reported via the read command, also added a bit of code to update a new global keyupresult boolean variable which always represents the keyup status.

Then i just added a simple boolean function to report the state of this variable.

When a char comes through via read, i just query if it is keyup, or keydown, and react accordingly.

Long story short - its working beautifully and i can now make fabulous use of the envelopes =D keydown trigger noteON, keyup triggers noteOFF. =D

It REALLY smooths out the cutting and chopping sounds you can get from fingerdrumming with long samples. Great progress, very happy tonight :)
 
2 problems

1) the minipac is a usb interface going through a ps/2 adapter into 4 soldered cables into crimp pins into breadboard, to the teensy. It works well for hours then irregularly fails to operate at all for a bit, and no amount of wiggling, disconnecting, rebooting of the minipac or the teensy will fix it, then it just starts working again, apaprently without me having done anything. It's worked all evening now (4 hours), through around 30 reboot/download cycles, but might not work tomorrow.

I think this might be a curiosity of the ps2 adapter / minipac ps/2 emulation mode rather than accuracy of comms from the teensy.

2) it works great _most_ of the time it is working but too many button pushes in combination can throw up weird chars for a bit. seems to get out of sync.
break testing shows 4 buttons pressed together works almost every time, then all of a sudden, i press the same 4 buttons and get one character. Release triggers all 4 keyup events.

=sync issue

i can probably fix number 2) but don't think i'll ever resolve number 1)

considering two trellis PCBs and hard soldering some cables to them.

In more positive news i have a lovely smooth RGB fade between LCD backlight colours =D
 
Quick update:

1) PS/2 issues resolved. Funny characters were eliminated by moving the samples into SPI Flash memory instead, and intermittent functionality was resolved by hardwiring the PS2 pins from the teensy straight into the USB wires of the minipac. Problem solved. Works great

2) samples are now loading in FLASH rom giving me 16Mb of low latency, low CPU load access to samples. Polyphony increased 2 fold, now looking at 8 to 9 44Khz mono samples running at the same time. C locked at 120Mhz for reference. Could be doubled if I go for 44khz 8bit u-law, i'll keep this option in the back pocket if i run out of CPU time.

3) Playing with a sequencer now, struggled at first but timing is now working better. Had to use multiple timer libraries to get a good balance of sequencer / lcd update / loop priority. Getting there with one bar at the moment. LCD now has button feedback and a sequencer position bar system in place.

4) Button upgrade. I stupidly economised when i bought the bits and used the cheapest microswitches they sold. This was DUMB. I am building a musical instrument, and the buttons are the keys to my piano.

The buttons were far too heavy to press, it was quite tiring. So i removed the springs so only the microswitch resistance is applied to the button press. This was much improved but I still felt it was too heavy (and loud!), we want a very light press to work just fine.

So I have bought 16 x Rolls Royce microswitches Cherry D44X, which are AWESOME. quieter click, much lighter touch to trigger. I also bought one of the Sanwa buttons used on the MidiFighter which DJTechtools did loads of research on to design. They chose Sanwa as the best switch for the job, and once I've got the Cherry microswitches in the feel is very very similiar, in fact I prefer the feel of mine over the Sanwa switch - there is not much in it. Happy Bunny indeed.

unnamed.jpg

Next up: Pad LED output, rotary encoder, pots, panel LEDs, and finish all the wiring up for stage 1, so i can tidy up and get on with the code. Still need to put a backplate in with sockets/buttons for reset, line outs, usb, headphones, microphone etc. One step at a time.
 
Yesterday, I gave you some more "reserve" cpu cycles ;-)

Ooooh, Frank you keep making my project timeline shrink - first SPI flash sampling and now higher polyphony with FIFO :)
Along with those delicious Cherry microswitches, this has been a good birthday :)

Thank you, I'll upgrade tomorrow and do a before and after with 44khz Mono, see what the beneifts are

I can pull complex high level objects together very well (I'm a project manager for building controls by day), but low level stuff like SPI flash isn't my forte - that would have taken me weeks, I'm convinced. So thanks again, really amazing :)
 
It's been a while since I've done an update; In brief:

1) I've not done much, I've been busy beta testing and setting up a company (www.paynetech.co.uk), while wrestling my twins into submission day to day.
2) I've added the whole project to github here: https://github.com/Pensive/Beats-by-Teensy
3) I'm heading to complete stage 1) (complete electronics) ASAP.

This involves,
  • connecting and talking to, the button LEDs
  • Replacing the rotary encoder (Which was TERRIBLE chinese crap - what's the use of detents if they don't reflect the gray code?)
  • Connecting up the slider
  • fixing a button i melted with my soldering. (Yes, I soldered oversized crimp plugs to the button pins...I'm a bad bad man.)
  • connecting up remaining panel mounted LEDs
4) then Stage 2) I will make everything talk to, and respond to, midi. This will allow a DAW to act as a sequencer. It will also get me to a stage where i can get Ableton to use my device as a controller for PC-based sound if I wish. So ICan actually get the device doing what it is intended using Ableton as the audio engine.
5) then Stage 3) I will work on the embedded audio library side of things, so that ableton (or cubase etc.) will simply be recording, and playing back the midid commands, and all sound is generated by the device.
6) then lastly Stage 4), and only if, I can get it to work, I will try and build the embedded sequencer functionality.

Why am i leaving the good stuff till last?
My experiments with Teensy-LC left me wondering if I would burst the banks of either equipment capabilites, or (more likely) my coding capabilities to make this happen. interrupts are a pain and i had quite a lot of trouble getting a 32 step sequencer to trigger midi events on time.

That's all for now folks!
 
Hi Pensive,
Thanks for sharing your progress, information and code. its very valuable, as i'm also building a teensy based musical instrument (https://vimeo.com/129864363)
Best, tom

That looks great!!

I'm wondering if my stage 4 should be a 32 step sequencer instead, with stage 5 being a 96PPQN sequencer.

The trouble with a 96PPQN sequencer in the embedded world is, I need to store the sequence as a MIDI file in memory, which would not be hard as a one shot, but inserting events into the midi stream is the challenging part, and how quickly will i run out of CPU/memory? I'll leave it till last!! :) :)
 
I was not feeling the AUDIO CPU (ex / AUDIO / MemoryAndCpuUsage ) loading as a true measure when I was looking at FFT as kpc was massively dropping the code behind and sharing the load over time. I was wondering if some cycles or usage were not accounted for. Can you think of 'measurable busywork' your app might run for the buttons, LED or I2C lights that will give you a measure of free time and real loop() cycle rates just to see how real world that is and if you still have working sound and >85% free CPU? If you can do that now and see it true you'll stay happy.
 
Yes; Essentially I've got all the unnecessary stuff running through metro, the idea being that the metro function is the point that gives as the cpu usage begins to rise, so the sound should continue (interrupts), and the PS/2 buttons should respond (interrupts) and the rest of the input will run as often as the program loops, but the lcd display can stop updating /slow their update to offer cpu cycles to other functions. Of course it will still fire in these conditions but it will slip a bit according to how busy the cpu is.

I can determine whether or not Metro is hitting it's millisecond targets, and report a percentage value according to what percentage of it's millisecond targets it is falling behind.

It wouldn't take much to beast the cpu into submission to get a calibration guage of what happens to the metro sequence under heavy load. Detecting those conditions and flagging up a warning would be easy.

It's a bit clunky but it would actually give a reasonable idea of what is going on, certainly in the context of my project.
 
Wierd little crash on the PS/2 Keyboard interface, I first suspected there might be 2 chips but there are not https://www.ultimarc.com/images/minipac_diag.jpg

So I've crashed a part of the chip while the rest of the chip is still kicking.

Either way this is far from ideal, long term. I may need to revisit the button interface with something like this:

Give me 10 minutes i'll upload a video
 
Hi Pensive,


I am wondering what kind of latency you are experiencing?

Playing a RAW file from an SD card triggered by an interrupt, I am getting around 10ms using the onboard DAC. I get a couple of ms less when playing from memory and not SD.

If I create an array and then use an IntervalTimer to step through it I get a latency of less than 1ms.


James
 
I am wondering what kind of latency you are experiencing?

Playing a RAW file from an SD card triggered by an interrupt, I am getting around 10ms using the onboard DAC. I get a couple of ms less when playing from memory and not SD.

If I create an array and then use an IntervalTimer to step through it I get a latency of less than 1ms.


it should be possible to do somewhat better than 10ms, and close to 3ms with flash/SPI flash. there's also the old "open-file-by-index" story, which might improve things or not. fwiw, there was some discussion of latency here:

https://forum.pjrc.com/threads/27409-Play-RAW-from-Serial-Flash (p1)

and again on p3 https://forum.pjrc.com/threads/27409-Play-RAW-from-Serial-Flash?p=62121&viewfull=1#post62121
 
Wierd little crash on the PS/2 Keyboard interface, I first suspected there might be 2 chips but there are not https://www.ultimarc.com/images/minipac_diag.jpg

So I've crashed a part of the chip while the rest of the chip is still kicking.

Either way this is far from ideal, long term. I may need to revisit the button interface with something like this:

Give me 10 minutes i'll upload a video

My "10 minutes" abysmal.

I blame the iOS app not working :)

https://youtu.be/wAvDQHKokvQ
 
Thanks all.

I timed the SD.open function and it takes 3ms for the RAW drum sample I am testing this with.

Reading those threads — it can take as long as 2.9ms to run the audio update? — which may account for the variation I was seeing.

Is there a way to force an audio update straight after a play? (if that makes any sense at all)
 
Reading those threads — it can take as long as 2.9ms to run the audio update? — which may account for the variation I was seeing.

2.9ms is because of the buffer, so that should be fairly consistent. 128 samples ~ 2.9ms @ 44.1k

my understanding is that any variation you'd see is on top of that - like when exactly the interrupt happens and so on. as for wav vs raw, in my experience it doesn't make a significant difference.

Is there a way to force an audio update straight after a play? (if that makes any sense at all)

one obvious way would be to try with a smaller buffer, like 64 or 32. i haven't looked into it but AFAIK the API was designed around 128, so that might not be very straightforward. IIRC, there was also talk of data pre-fetch occasionally.

are you using a codec? or A14/DAC? if the former, take a look a the old hughpyle/i2s stuff, it would allow you to adjust the buffer size fairly easily but it lacked all the rest, of course. if the latter, you could try to hack up something yourself... somewhat like this ? : https://github.com/BleepLabs/Delaydelus --- well, i guess. i haven't bothered to actually read through the code but it seems to use some unbuffered DDS scheme.

edit: and sorry, pensive for derailing the thread. probably this discussion should be moved somewhere else
 
Last edited:
Status
Not open for further replies.
Back
Top