[Help] Loading a randomly selected .wav file into arrays (arrayL, arrayR)
@atux said:
Nice patch.
Just one question: what is the easiest way to make the previous .wav file not stop when the next file starts? That way you would have some overlapping sounds (at most in a certain time interval all the files could play at the same time).
Thanks,
Hey, thanks for the kind words!
I'm still pretty new to Pure Data myself, so I don’t have a full solution yet but I totally see what you mean about overlapping sounds.
From what I understand, one way to achieve that would be to use multiple [readsf~ 2] objects, one for each potential overlapping sound, and cycle through them. So instead of always opening the next file on the same player, each random file could be routed to a different [readsf~], letting the previous one finish naturally.
If anyone here has a cleaner approach or example, I'd love to learn from it too!
[vline~] may not start at block boundaries
@porres Thanks for your interest! This is an envelope generator that is trying to copy and improve on an effect I used in a piece way back in the '90s. It was originally done with a Valley People Gatex, which I'm about to give away to the friend who turned me on to them. Anyway, if I set the Gatex to 0.2s release time, a 60dB range, and then ride the threshold to constantly trigger on an external key (for which I usually used speech so it would be fast and unpredictable), I'd get a pleasing chattering sound with a consistent soft click on the attack. Even though the release is so short, the triggers are coming awfully fast so the gate is retriggering before it has had a chance to fully close.
I made some recordings of the Gatex and tried to measure what it was doing, but as these things often go, I found that the Pd simulation sounded more true to the original with parameters that didn't quite match what I had measured. The release curve I'm using is much steeper at the beginning, release time much longer, and the attack curve is longer and logarithmic. I kept the 20ms sustain time as is. I found that if I retriggered the same [vline~] before it had had a chance to fully release, it would either pop too much (if I made it jump to 0 first), or had inconsistent attacks (if the new attack didn't start from 0), so that's why there's two of them computing the ramps and hold. I'm outputting whichever one is higher at any given moment. When a new trigger comes in, I look to see which EG is lower (and thus not seen on the output) and route the new trigger to it. It first jumps to 0, but you don't hear it click because I'm outputting the other one at that instant.
To control the curvature of the attack and release, I use [vline~] again to synchronize the values used to shape the attack and release via [pow~]. Finally, I noticed that the Gatex had a unpredictable amplitude variation, probably based on the key signal at the moment the trigger was detected. That's what the randomized volume stuff is for, although the Gatex's actual variation is only 3 dB, if that. I'm not trying to copy their detection algorithm because for my music there's usually been no correlation between the main channel and the side chain, so I just use randomized [delay]s to trigger it, which is how my troubles began. Without the intervening [vline~], the unsynchronized random volume part added unpredictable discontinuities, especially when the trigger density was high.
Here's some sound: jittery gate demo.mp3
sigmund~
I am attempting to use sigmund~ to detect low frequencies.
I am putting an osc~ to detect lowest frequencies.
It seems sigmund~ cannot detect frequencies below 45 hertz.
Here is the object I am using:
sigmund~ -hop 65536
what "flag" causes [keyname] to change behaviour?
@ArturJD said:
A parallel to you observation is the fact, that PD has no notion of undefined/None/null. Many objects already have the "carry bang" or "bang when done" feature which avoid the whole trouble altogether – and bang is often the thing that works as "null" ([route] object is a good example).
Sure, e.g. the Pd [list xxx] operators fairly consistently use bang to indicate an empty list (a good convention, I think).
However...
But this doesn't necessarily mean, that we must be left to deal with asynchronous absence of message detection.
In this case, it is asynchronous because the condition that distinguishes valid-0 from invalid-0 is asynchronous. That is, the reason why I used delay is because the distinguishing signal is literally in the future, and you can't know the future at the moment of receiving a 0. If the 1 0 1 0 problem can't be resolved in the backend, then there is no choice but to wait and see if the latest 0 is a real key-up or not.
But using [delay] is better than nothing of course
I would rather prefer to have a method, which flags out the patcher state causing this discrepant behaviour and routes [keyname] output to a sub patcher with a proper message handling...
Look at the available information... In the "bad" case, you get alternating 1 and 0; in the good case, you get a stream of repeated 1s. You can't know which you will get in advance, but you can detect the "good" status upon the first repeating keystroke and switch to the streamlined logic at that moment (and keep it that way for the lifetime of the patch).
EDIT:
You might also add logic to detect the bad state and also switch off the right-branch check, though I think the check is not terribly expensive ("premature optimization is the root of evil").
Pd vanilla can do "gate" by [list prepend] --> [list trim] --> [route] but I'm lazy this morning.
hjh
Granular in pd
@KMETE said:
@ddw_music
is it possible to decide the size of the grains? in ms?
As the old mathematicians used to do, I'll "leave that as an exercise for the reader." (It's a bit of a funny question -- of course it's possible, even though this specific patch doesn't do it for you.)
This patch defines terms as: Given a trigger rate (grains per second), the grain inter-onset interval in ms is 1000 / rate. Then the grain duration is ioi * overlap = 1000 * overlap / rate.
You could simply drop the multiplication and redefine the "overlap" slider to be grain size (and edit [pd globals] to route in the right way).
I always preferred the "overlap" definition because the sound is more consistent when changing the grain rate. If you use grain size directly, then slowing down the grain rate decreases the density. That's not my first choice, although it may be useful in cases where you want the sound to be "pulled apart."
hjh
Gem not loading abstractions
------------------ done with main ----------------------
Connection from 'pd' to 'pd-gui' on 127.0.0.1:58808
Tk 8.6.8
Detected font: DejaVu Sans Mono
Using font: DejaVu Sans Mono bold
Loading plugin: /usr/lib/puredata/tcl/pd_deken.tcl
[deken] Platform detected: Linux-i686-32bit
Loading plugin: /usr/lib/puredata/tcl/pd_docsdir.tcl
[deken] Platform re-detected: Linux-i386-32bit
The Pd window filtered 11 lines
Pd documents directory: /root/Pd
The Pd window filtered 13 lines
menu_doc_open /root/Pd/externals/Gem/examples/06.particle 02.fountain.pd
gemreceive __gem_render $1
... couldn't create
... you might be able to track this down from the Find menu.
gemreceive __gem_render_osd $1
... couldn't create
gemlist
... couldn't create
GEMglColor4f 1 1 1 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_AMBIENT 0.2 0.2 0.2 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_DIFFUSE 0.8 0.8 0.8 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_EMISSION 0 0 0 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_SPECULAR 0 0 0 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_SHININESS 0
... couldn't create
GEMglPushMatrix
... couldn't create
GEMglPopMatrix
... couldn't create
GEMglFlush
... couldn't create
gemlist
... couldn't create
part_head
... couldn't create
part_color
... couldn't create
part_draw
... couldn't create
part_size 1
... couldn't create
part_gravity 0 -0.01 0
... couldn't create
part_velocity sphere 0 0.2 0 0.2
... couldn't create
part_source 25
... couldn't create
part_killold 45
... couldn't create
gemglutwindow
... couldn't create
GLdefine GL_LINEAR
... couldn't create
GLdefine GL_EXP
... couldn't create
GLdefine GL_EXP2
... couldn't create
GLdefine GL_COLOR_BUFFER_BIT
... couldn't create
GLdefine GL_DEPTH_BUFFER_BIT
... couldn't create
GLdefine GL_STENCIL_BUFFER_BIT
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglViewport 0 0 500 500
... couldn't create
GEMglDisable GL_FOG
... couldn't create
GEMglEnable GL_FOG
... couldn't create
GEMglFogf
... couldn't create
GLdefine GL_FOG_DENSITY
... couldn't create
GEMglFogf
... couldn't create
GLdefine GL_FOG_MODE
... couldn't create
GEMglFogf
... couldn't create
GLdefine GL_FOG_START
... couldn't create
GEMglFogf
... couldn't create
GLdefine GL_FOG_END
... couldn't create
GEMglFogfv
... couldn't create
GLdefine GL_FOG_COLOR
... couldn't create
GEMglDisable GL_COLOR_MATERIAL
... couldn't create
GEMglDisable GL_AUTO_NORMAL
... couldn't create
GEMglDisable GL_NORMALIZE
... couldn't create
GEMglShadeModel GL_FLAT
... couldn't create
GEMglLightModeli
... couldn't create
GLdefine GL_LIGHT_MODEL_TWO_SIDE
... couldn't create
GLdefine GL_FALSE
... couldn't create
GEMglLightModeli
... couldn't create
GLdefine GL_LIGHT_MODEL_TWO_SIDE
... couldn't create
GLdefine GL_TRUE
... couldn't create
GEMglEnable GL_LIGHTING
... couldn't create
GEMglEnable GL_COLOR_MATERIAL
... couldn't create
GEMglEnable GL_AUTO_NORMAL
... couldn't create
GEMglEnable GL_NORMALIZE
... couldn't create
GEMglShadeModel GL_SMOOTH
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_AMBIENT 0.1 0.1 0.1 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_SPECULAR 1 1 1 1
... couldn't create
GEMglMaterialfv GL_FRONT_AND_BACK GL_SHININESS 100
... couldn't create
GEMglDisable GL_LIGHTING
... couldn't create
GEMglClearColor
... couldn't create
GEMglClear 17664
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglDisable GL_LIGHTING
... couldn't create
GEMglViewport 0 0 500 500
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLineWidth 2
... couldn't create
GEMglColor3f 1 1 1
... couldn't create
GEMglBegin GL_LINES
... couldn't create
GEMglVertex2f 0 -6
... couldn't create
GEMglVertex2f 0 6
... couldn't create
GEMglEnd
... couldn't create
GEMglLineWidth 1
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglViewport 0 0 250 500
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglViewport 0 0 250 500
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
gemlist
... couldn't create
gemlist
... couldn't create
GEMglGetFloatv GL_STEREO
... couldn't create
GEMglColorMask 1 1 1 1
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglColorMask 1 1 1 1
... couldn't create
GEMglColorMask 1 1 1 1
... couldn't create
GEMglClear
... couldn't create
GEMglClear
... couldn't create
GEMglClear
... couldn't create
GEMglClear
... couldn't create
GLdefine GL_COLOR_BUFFER_BIT
... couldn't create
GLdefine GL_DEPTH_BUFFER_BIT
... couldn't create
GLdefine GL_STENCIL_BUFFER_BIT
... couldn't create
GLdefine GL_ACCUM_BUFFER_BIT
... couldn't create
gemlist
... couldn't create
gemlist
... couldn't create
GEMglColorMask 1 1 1 1
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglFrustum -1 1 -1 1 1 20
... couldn't create
GEMglMatrixMode GL_PROJECTION
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglLoadIdentity
... couldn't create
GEMgluLookAt 0 0 4 0 0 0 0 1 0
... couldn't create
GEMglDrawBuffer GL_BACK_LEFT
... couldn't create
GEMglClear
... couldn't create
GLdefine GL_COLOR_BUFFER_BIT
... couldn't create
GLdefine GL_DEPTH_BUFFER_BIT
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglDrawBuffer GL_BACK_RIGHT
... couldn't create
GEMglClear
... couldn't create
GLdefine GL_COLOR_BUFFER_BIT
... couldn't create
GLdefine GL_DEPTH_BUFFER_BIT
... couldn't create
GEMglMatrixMode GL_MODELVIEW
... couldn't create
GEMglClear
... couldn't create
GLdefine GL_DEPTH_BUFFER_BIT
... couldn't create
gemlist
... couldn't create
gemlist
... couldn't create
GEMglReportError
... couldn't create
gemlist
... couldn't create
Miller's Pitch Shifting Example From His Book
For future students & fellow nerds, here’s what I was suggesting:
See? Opposite sign, contrary to the text.
RE sample rate, let s’ = s/R (in English: specify the window size in seconds instead of samples). Then:
which is what the example patch G09 is computing for the phasor frequency.
RE Hann windowing with 4x overlap, it definitely sounds worse in this case, still not sure why when it's better for the FFT.
time domain overlapped windowing.zip
I have a faint memory of an explanation in Miller's book why the positive part of the cosine function is a useful windowing function for time domain stuff, but I can't find it. Maybe I just saw it used a lot in the audio examples.
Miller's Pitch Shifting Example From His Book
Hmm, it's interesting that these kinds of time-domain algorithms use cosine-shaped windows and 2X overlap, whereas FFT resynthesis algorithms use Hann windows and 4X overlap. I've fooled around a little with FFT resynthesis using the former, and the sound is just a little coarser, which is to say I was surprised it wasn't terrible. I wonder if for something like time-domain pitch shift Hann+4X overlap would sound better (i.e. have softer windowing artifact) and if so, why.
(This question occurs to me just as I'm preparing to have no free time for a week so that's why I'm not just trying it and posting my results with further questions)
Just got my MIDI Violin! Here are some notes on it and how to use it with PD
@whale-av Hey, sorry I never replied- I just saw your reply now after I bought the instrument. I ended up getting the BOSS GP-10 as a MIDI interface for the instrument. I knew the GR-55, SY-300 and SY-1000 would work as well, but didn't know about the GI-20. Maybe it would've been more affordable...
Here are my notes. Happy to hear anyone else's experiences or ideas about how I can get the most out of this device:
1)The instrument has screws on the back that you can turn to increase/decrease the sensitivity of each string. I've adjusted these a bit with dealing with the problems mentioned below in observation 9)
2)The GP-10 also has some settings for more or less dynamic contrast. I've experimented with setting these differently, though setting "Dynamics" to 1 and "Play Feel" to FEEL 1 seems to be the best. Changing these doesn't seem to do anything for the problem in 9).
3)I have the GP-10 set to MONO mode, rather than poly mode so that each string outputs to a separate MIDI channel.
-
The output to separate channels works well if you do clear attacks with the bow (or use pizzicato of course). The attacks need to be clear whenever you switch to a different string. Raising the sensitivity (cf. 5)) allows you to have clear attacks that are still somewhat quiet.
-
As long as a note is sustained, you get continuously updated bend values, which can be combined with the original noteOn value to get exact pitches and perform glissandi. I combine the two values in Pure Data with math objects. noteplusbend.pd
-
The MIDI velocity value does not update continuously, but in PD I can use the velocity's value as a switch to allow the Audio-in (which also comes in through the GP-10's USB) to control the volume of the MIDI-activated note via [spigot].
-
Because attacks with the bow need to be clear, if you fade in a note very gradually with the bow, it won't be detected as MIDI.
-
By combining 6) and 7) I can construct patches in Pure Data so that a certain sound will play and be controlled purely by the Audio-input and that others will be activated by MIDI+Audio-Input. Eg. I can fade in a sound, crescendo with an up-bow and then attack crisply on the down-bow to activate other sounds.
-
There are some issues with stable pitch detection when playing double-stops (diads) on two neighboring strings. It seems when doing so that there's some interference. However, for some reason, playing smaller intervals (major 3rds or lower) seems to work better than larger intervals. And avoiding open strings helps as well.
-
The pitch detection of 9) could be ameliorated by removing the bend value from the equation, but of course glissandi/microtonality would be lost as a result.
-
The E string (the highest one) gives the quietest, least consistent output. Pitch detection suddenly falls off after the first octave.
Best way to pitch track a Bell Kit instrument?
Hi there —
I'm trying to detect pitches from a Bell Kit instrument for a music education app; and so far I'm having trouble picking up MIDI pitches above the 90s/100s; which is the target range for this instrument.
Here's a test patch I'm using to determine whether [sigmund~] or [helmholtz~] does a better job at reporting higher pitched content. It seems that sigmund~ is generally better at detecting the higher pitches but it seems to stop picking things up above the MIDI pitch 100 range; which is the range of the second recording in the zip file. Can anyone tell me if there is a limit for these objects for higher frequency detection, or suggest parameter configurations or different methods for tracking this instrument?