Hey all -
Attached is a simple CC generator, tied to the MIDI clock.
If your synth is limited to simple LFO, and you want a few more patterns, this helps spruce things up a bit.
Input: MIDI clock & notes. Notes are ONLY used to restart the pattern.
Output: The selected pattern is sent out at the selected rate on the selected CC on the selected channels.
You can change the patterns by altering minVal, maxVal, stretch & pattern values on the UI. Kinda fun just to play with the UI.
Some usage notes -
- You do not need your DSP engine on for this to work. It operates purely in the MIDI & math realm.
- You do, however, need to feed it a MIDI clock.
- You can make minVal > maxVal to invert the pattern.
- The "Beats" parameter simply tells it how many beats it should use before it should repeat the pattern you see.
- "Pattern 8" is just random steps; changing anything picks new random steps.
I'm still a noob at pd, this is only my 3rd or 4th patch. This is pure vanilla, I think. My only 'out there' object is usage of expr.
I allow for multi-channel selection, since my primary usage is for guitar synthesizer. I feed this into 6 different channels on my synth, one per string, for lush sounding processing.
If there is interest for such a utility, I may add the ability to save & load presets. At the moment, I use it mostly during improvisation, so it's fine as-is.
Feedback welcome! Especially if there are things I should have done differently...
Hello all -
Despite warnings to the contrary, I've been able to get several MIDI commands to work fine under Windows 7, including [notein], [bendin], [midiin], [midiout], [ctlout] & [midirealtimein]
Sysex data doesn't show up anywhere. I've tried using [sysexin], [midiin] and [midirealtimein]. Other MIDI real time messages, such as MIDI clock messages, show up properly using [midirealtimein].
Anybody have luck with receiving sysex messages in Windows using 0.43.4? Any thoughts?
I need to basically mix 6 different audio streams. Simplest way possible, no need to set levels, they're already set.
I have seen some example code where an object has multiple audio streams feeding the **same** inlet. I've tried that. It seems to work just fine.
Is it safe to feed multiple audio streams to one audio inlet on an object? Will it always work? Or should you explicitly add the streams (with +~)?
My hunch is that you should add the streams, and not assume what the object will do if given multiple input streams, since objects are written by all kinds of folks...
I couldn't find this explicitly stated in the online books, I may have missed it...
As my first project to learn pd, I chose to write a very simple guitar synth, that will take 6 discreet channels of MIDI input, including pitch bend information, and play a simple sawtooth sound. 6 discreet channels is important to capture the full guitar performance, because that's exactly what a guitar is...
***Thus, to REALLY play this patch, you need a 6-channel instrument that generates MIDI output... E.g., a guitar with a Fishman TriplePlay pickup or the MIDI output from a guitar with a Roland GK3 driving a Roland VG unit or similar. ***
Your PBR (pitch bend range) and your starting channel are configurable, and must agree with your transmitting midi guitar controller.
This patch is actually quite fun to fool around with. With a pitch bend range of 12 or 24, you can run a slide all up & down the neck and it works perfectly!
Three files attached:
- sjrbPDGS1.pd - the guitar synth main program
- SynthModule-saw-1.pd - an abstraction used for each of the 6 channels
- Bendin-mtof-freq-calc-expr.pd - This is basically a 'help' file to explain the formula & let you test it. It is not needed to run the synth.
Frequency calculation, using notein and bendin:
I had a VERY hard time finding how to actually honor pitch bends in pd. Lots of folks have asked the question out there on the web, only to receive kinda useless theoretical answers. It took me a while to work out the formula:
[expr $f2*pow(2, (($f3*($f1-8192))/98304))]
$f1 = bendin value
$f2 = mtof value from midi note from notein
$f3 = pbr, pitch bend range
freq-w-pb = freq * 2^((pbr/12)*((bendin-8192)/8192))
Which simplifies to:
freq-w-pb = freq * 2^((pbr*(bendin-8192))/98304)
Note similarity to:
next-note-freq = freq * 2^(1/12)
I.e., it's all about powers of 2... In increments of 1/12ths, it's your semitones. But when applying pitchbend, you don't want increments of semitones, you want increments of 1/8192ths of pbr # of semitones.
Bendin values range from 0-16383, where:
0 = bend the note DOWN by pbr# of semitones
8192 = NO bend
16384 = bend the note UP by pbr# of semitones
Yes, I know there is a one-off error (max is 16383, not 16384), and you can't actually get all the way to 16384, but it's so close nobody will ever hear the difference...
I hope this makes sense!
Pitchbend is a 14-bit value, requiring TWO bytes of data from your MIDI controller, one with MSB and one with LSB. Some gear only sends MSB (0-63=down and 64-127=up). The good news is that bendin properly reports it in the 0-16383 range, so no special coding is needed. However, the bend will NOT sound smooth, there will be audible steps, especially when using high PBR values. You'd need to modify this algorithm with a [line~] somewhere to even out the steps. Or stick to low PBR values when using very old gear.
Feedback welcome! I've just started learning...
For even more MIDI functions, open up help for one of those objects. Towards the bottom of each help page is a link for pd Related_objects. I have found it very, very helpful to constantly scan the related objects when I'm doing almost anything in pd.
Regarding pd dropping some data (e.g., no sysexin), I doubt it's a driver issue, since I've seen these pd issues on multiple devices on multiple systems. These systems work perfectly outside of pd, so my Windows & device drivers work fine.
It's either different code, or a build/compiler directive problem.
Ahhhh...... Do I want to look at the code? I seem to enjoy rabbit holes...
I don't use python, so I can't test your patch.
As an FYI, I just attempted to receive MTC (MIDI Timecode) into pd, and I'm sad to report it doesn't work (on Win7). It should show up as a sequence of pairs of bytes, the first byte always xF1. (Look at the quarter-frame message definitions at the bottom of the Wikipedia article on MIDI Timecode.) The xF1 (241 dec) appears, but not the actual data byte.
The xF1 appears on [midiin], but without the databyte it is useless.
Attached is a very simple MIDI diagnostic pd patch. It's not pretty, but it's very helpful at telling you what is on the MIDI bus that is visible to pd, and which messages report it. It is only helpful at showing you where to start...
(pd-extended, 0.43.4, Win7)
A couple of clarifications, following the links in your earlier posts:
My experience is with MIDI Clock on pd, which supports start/stop & tempo, useful for syncing effects across systems, but not for communicating song position. [midirealtimein] works for MIDI Clock.
I do not use MIDI Timecode, which is basically a MIDI implementation of SMPTE and allows for song position pointers. Since MIDI Timecode uses sysex messages, I would wager that if you can get sysex to work on pd, you can get MIDI timecode to work on pd.
There is a lot of really inaccurate info out there on these two protocols, and the jargon is inconsistent from app to app & community to community. Wikipedia thankfully has good data on the specifics of the two:
To be honest, I don't trust the 'blacklist'. Most of those links had '?'s, which meant that the issue was never confirmed with a second report - all it took was one person to have an issue he couldn't resolve to get a product on that list. I've used MIDI for many years, and in my experience, even large sysex dumps can be made to work. Resolving issues with large sysex dumps usually requires finding & setting a buffer size somewhere that was set too low for bulk data. (Such large syex dumps are used to backup device settings for synthesizers & effects processors, etc., for the purposes of restoring the device's state at a later time.)
My strong suspicion is that the only reason pd users report issues with large sysex messages is that the buffer is not visible/configurable, that it's a hard-coded fixed tablesize somewhere.
I've never had an issue with sysex in small chunks, across a lot of gear & software & versions of windows over the years. (Other than pd's inability to receive sysex...)
Haven't used python. I am able to get MIDI clock messages using [midirealtimein] in this patch:
The only MIDI issue I've had with pd is with sysexin - everything else I've tried in MIDI has worked fine (including PCs, CCs, notes, clock & sending sysex). Sysex input doesn't show up on [sysexin], [midirealtimein], or [midiin].
pd-extended, 0.43.4, Windows
I've seen this behavior on other MIDI realtime data, e.g., MIDI clock. I forget the exact circumstances, but I've definitely seen it.
At the moment, I forget if this was a pd error or mine. I did a lot of testing with loopMIDI & MIDIYoke, with my output=my input. I actually found this to be a very useful configuration & ultimately made my code handle this scenario (e.g., input & output being the same loopMIDI port). That way I could xlate one type of message into another, a useful mental model for what I was trying to do.
Are you sure your midi monitor isn't creating a loop?
Does this happen with NO MIDI devices configured, i.e., all MIDI ports set to 'none'?
I wish I COULD see it on sysexin. I have not successfully been able to receive sysex (Windows, pd extended 0.43.4).
I'm curious - what version of pd are you running?
I haven't used it, but I suggest reading up on JACK, the audio routing utility. Most apps assume they're talking directly to hardware, which makes routing audio signals between apps difficult. Utilities such as JACK add a logical layer, allowing you to utilize virtual audio jacks. So you'd create a virtual jack, send your system sounds to it, then use that virtual jack as an input in pd.
This works for audio just like MIDI Yoke does for MIDI.
Hope this helps,
I'm still learning this, but here's what I know...
Beyond Nyquist, strange stuff happens.
Nyquist frequency is 1/2 of the sample rate. In theory, you can't do ANYTHING in the digital realm above Nyquist, because it is the maximum frequency you can reproduce at a given sample rate, i.e., when each sample is +1,-1,+1,-1..., it takes 44.1K samples to represent a 22.05K frequency.
Also consider the possibility of a 22.05K frequency, where the sample just happens to land on every 0 crossing. In this case, the sound is perfectly 'invisible' to the digital realm. And in truth, you are just as likely to experience this as you are to get a perfect +1,-1,+1,-1... series. Thus, very strange things happen even as you approach Nyquist. So a 44.1K sampling rate is actually fairly useless at representing signals above 20K. Fortunately, 20K is beyond the range we can hear.
So what happens when you try to represent a high frequency signal that CANNOT be represented digitally because there aren't enough "plotting points"? Harmonics at best, noise at worst.
As to how this can make 1K look like 44101K, take a peek at the first chart under "Sampling Sinusoidal Functions" at the following link (two different sinusoids that fit the same set of samples):
Over in the abstraction area there are some state-saving abstractions, have a look:
I believe what is happening in your example is that the packed list is just "one" signal, which is why the whole thing goes out one outlet (not just part of it). Nothing goes out the right outlet, there was only one signal, there's no 2nd signal to go there.
For list management, I suggest reading up on the list objects such as
I'd also read up on the message box manipulation messages, open HELP for a message box and click on the box that says:
I hate to say this, but I did not have a lot of luck with this patch. I would occasionally get a good performance, but then it would go chaotic on me, like there was a feedback loop or something going on.
I believe this was largely the setup required. I didn't understand it, couldn't dial it in. My bad.
I'm learning a lot reading the code, thank you.
I am also working on guitar processors, synthesis. I look forward to your next posts!
I believe the documentation is incorrect. I can send values from -8192 to +8191 to [bendout] and it accurately transmits them in a 2-byte pitchbend message. Confirmed in MIDIOX.
I have confirmed that [bendin] works similarly. Some old products only send a 1-byte wheel event, and I'm happy to report that [bendin] properly xlates those to the -8192 to +8191 range.
So both objects work perfectly with the full 14-bit range. Further, they play nice when others do not.
(I'm a Win7 user.)
Just as an FYI, you may find the attached handy if you want to do math with these objects.
Basically you need to build a message & comma separate the elements. The patch at the end of this thread works perfectly for me. You pass it a list of numbers & it will properly format a message box & send it.
Some have reported you need to add a 1ms delay, but I haven't seen that. But it should be easy to enhance that patch to do so.
Still no solution for *receiving* sysex on Windows that I know of...
Depends on how big the audio file is or is intended to be... If it's small enough to be loaded into a table, consider looking into TableTool:
It has functions like normalize, which may be of assistance.
I ran across it yesterday while reading old posts, trying to figure some things out...
My bad - I'm able to open it. On a hunch, I tried a different audio device, whose drivers appear to be more robust.
Odd, my cheap onboard Realtek sound device performs better than my prosumer Edirol (Roland) device... Pd is a lot more stable after making the switch to the mobo sound - very counterintuitive. It was kind of touchy before. Realtek is everywhere, though, and maybe the drivers are more battle-hardened.
I'll provide some feedback later!