I appreciate it @pgatt. I’ve been facing a real challenges with this module. Here are a few:
Incoming audio is constantly streaming through a buffer. Let’s say that a grain spawns every 44 “ticks” (depending on sample rate) and starts playing at position
in the buffer.
- The 1st grain starts at position 44 in the buffer and begins playing at sample rate.
- 100 ticks later, the 2nd grain starts at position 44 in the buffer and starts playing at sample rate.
Here’s the really mind-bending part: Both samples will be playing at the same position in the sample. In fact, if the playback position in the buffer is not modulated, all the grains will be playing the same exact same spot in the sample, causing the huge spike in volume that you can sometimes hear.
Let me give you analogy, just in case that’s difficult to comprehend. Imagine that you’re on the beach with two video cameras. If you turn video camera #1 on at 2:00 PM and video camera #2 on at 2:03 PM, they’re both filming the same thing. That’s essentially happening in this module if you don’t modulate the location input. A casual user might get frustrated by this. But if I set up some internal modulation to apply to the position (like a triangle wave), it’s making an assumption on how the grains should be… I think that the term is, “scheduled”, which would make it nearly impossible for a power-user to tweak the module to their liking.
Attempting to find a solution to this conundrum, today I tried adding code to forbid two grains from playing at the exact same position the buffer. Essentially, the code said:
if this grain is playing at position i in the sample, and any other grain is also playing at position i, don’t add this grain to the output.
It may have helped? I need to run some more tests. But there was a serious side-effect: If you don’t modulate the position, only 1 grain can play the sample at the selected position, which is good. But as soon as you modulate the position, multiple grains can start playing (and overlapping) which increases the amplitude significantly due to the way the grains are summed. (Which sounds distorted and loud.) It didn’t feel like a real solution, but tomorrow I may run some more tests to compare before-and-after.
Another big issue is CPU usage. In order to get lush sounds, you need to increase the window value. (Window is how long the grain is.) But this causes grains to stay in memory longer, and more grains means more CPU time. One way around this is to decrease the maximum number of grains allowed in memory. However, sometimes you might want more grains, but with a shorter window. My solution so far has been to exposed those settings on the front panel, but it means that the module can go haywire. Maybe there’s some way of automatically throttling the settings to keep CPU usage under control without adversely affecting the sound, but if so, I haven’t figured it out yet.
If I put strict limitations on nearly any parameter, it means that there’s some fantastic and weird sound that will no longer be possible to achieve. My module Ghosts is a good example of this. Ghosts always sounds beautiful and interesting, but it’s repertoire is limited. So I have to decide if this module is going to sacrifice flexibility in favor of stability.
Anyhow, I wanted to share my thoughts. Maybe a community member will say, “Bret, you’re so dumb. The answer is clearly… [clever solution].”
- Bret