In the project I’m working on currently, I’d like a vinyl crackle sound and thought that storing this as a sampled array of floats (about 12 seconds @ 48kHz or so) would be the best way to be able to recall this sound whenever needed.
My question is what would be the best/easiest way to get a sound into an array of the samples? Maybe this would be called a wavetable?
I originally tried the Sample Data Export in Audacity, which gave me a .txt document of the samples (16bit @ 48kHz), as an example, the first 6 samples: 0.00323 0.00281 0.00104 -0.00082 -0.00140 -0.00079.
I then turned the data from ^that doc into a float array in a separate header file that I included in the project. I was then able to recall elements of that array but it was not a recreation of the original sound (kind of a white noise).
Something like this method would work best for me, somehow being able to spit out the sampled values into a text file.
I’ve also attempted to simply print the samples directly from the Daisy so I could copy/paste them into a document, but wasn’t able to get either the Arduino Serial or the VS Code Serial Port Helper extension working (both of these issues have been present for a while even though I was able to before).
(Theoretically, I should be able to sample the values to an array on the QSPI section of memory, but I’d rather not have to do this every time I want to build this project on a different unit. I’d like it to be something in a header file that I can just include in the project and any other projects I’d like to use this sound on in the future.)
TLDR- How do I get the sampled values of a file or the Daisy’s output floats into a text file?
I may be missing something but my settings for the Data Export are- Measurement scale: Linear, Channel layout for stereo: L Channel First (but I’m only exporting mono files). I don’t believe there is a mistake in the conversion. I have a python script just inserting commas after every float (I double check by making sure the values of random lines throughout match) and then I copy/paste that to a header file that looks something like this.
float DSY_SDRAM_BSS crackle_samples =
// sample data parsed with commas
Maybe I’ll give the Logger() another go but I haven’t been able to see the output of that or open the Arduino Serial monitor when connected to a daisy for a while now. (I believe there’s a bug with the Serial Port View extension in VS Code and can’t even get a list of my connections currently).
@three: I’m getting the exact same problem with Serial Port View. I’ve just posted a question on this topic in Daisy’s forum yesterday. I just thought that I’m the only one with this problem.
Vinyl crackle sounds are more like sparks or impulses on wave data. Normally it is a spike up and a spike down. If you’re getting noise (white noise) most probable cause is quantization, that you get when print some data with less accuracy than the measurement.
Yes, I have playback working other than this. I can playback a loop, the dry signal, or an oscillator, like your code. I appreciate the help!
It may help if I post the relevant code:
for (size_t i = 0; i < size; i++)
static size_t v = 0;
out[i] = VinylCrackle::crackle_samples[v];
if (v >= 576000) vi = 0;
// 576000: 12 secs of floats @ 48kHz
This is what I was using to test the output of the vinyl_crackle array.
It’s “good” to know that I’m not the only one having this issue. I’ll watch that post for any solutions.
What exactly do you mean by “sparks or impulses”? It sounds like I could maybe just artificially generate this type of sound with a function. Could I just generate arbitrary, momentary additions/subtractions to the sampled values I’m processing?
Would you be able to explain what those sparks/impulses would look like on data?
I think you may be right about the quantization, that seems like a probable cause given what I know.
Yes, I think you can artificially generate the crackles. Some years ago I was trying to manually remove crackles of a digital record from an old vinyl and noticed that they appear on wave as a very fast pulse going from zero to a maximum then inverting down to a negative minimum, and then returning to zero. Maybe something like c exp(-at^2)*tanh(bt) could do the job, with a, b and c constants and t the time. I think one has to adjust both the amplitude c and the number (or frequency) of crackles to be inserted in the wave. The amplitude should be equal to the inverse of frequency: the higher the number of the crackles per unit of time, the smaller their amplitude.
After trying out code similar to yours with data exported from Audacity, I only got noise too.
Then I remembered something.
You cannot init an array that is placed in DSY_SDRAM_BSS at compile time. If your sample is small enough, and you remove the “DSY_SDRAM_BSS”, it works for me. So, the export from Audacity is ok and compatible.
So, your original question remains, with larger samples, how to do it? I have to think about that one. You are using the basic Seed, right? I think the solution lies in using an SD card.
From that article, I’ve started creating a class to generate clicks. The main issue I’m running into is trying to use a gamma_distribution object to randomize the gap between clicks, however the parameters of the object can only be set on construction, so the gap can never be changed. I’m trying to come up with some way to work around this because the gap variation produced by the gamma object is less “artificial” sounding than randomized gaps using rand()
… _randomized_gap = rand() % (gap_duration * 2) + (gap_duration / 4);
Theoretically, click_duration can be extended to something like 30 to create some lower frequency disturbances (more like “thumps” than “clicks”) but this is just about right for my purposes.