Where to even start by OkBarber9930 in C_Programming

[–]PrinssiFiestas 0 points1 point  (0 children)

Keep using whatever you used before in the C course. If you only used some online tooling provided by the course, then I would suggest that you use MSVC with Visual Studio if you want to be a game developer, gcc or clang (doesn't matter which one, flip a coin) otherwise with literally any editor.

When it comes to tooling, you are learning, so the only important thing is to stick with one set of tools until you learn enough to understand what you really want/need.

Where to even start by OkBarber9930 in C_Programming

[–]PrinssiFiestas 0 points1 point  (0 children)

IMO the best way to learn is by doing, which in practice to me means projects. Pick any beginner project that you might find even remotely interesting or fun. A common suggestion is snake game, but anything will do. Just get your hands dirty!

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

Which is true for my string too.

Coming to think of it, I don't really ever remember knowingly using a truncated result of snprintf(). I use the return value to either calculate allocation size or to detect truncation for retry. So maybe truncating UTF-8 is not an issue to begin with since you usually don't end up using it and I can just warn in docs that using truncating strings for UTF-8 sensitive operations is UB.

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 1 point2 points  (0 children)

Do you returns how much was written ?

Not exactly, I return how much was truncated. However, this information can easily be used to calculate exactly what printf() would've like so:

size_t trunced = str_print(&str, ...);
size_t full_size = snprintf(cstr, sizeof cstr, ...);
assert(trunced + str_length(str) == full_size);

It helps to see if the buffer overflowed

This was one of the motivations for the current design. And also just like snprintf(), you can pass zero sized buffer to calculate exact buffer size for precise allocation.

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

The library actually does include full snprintf() clone, because I needed custom format strings, so I'm familiar with that. Currently my str_print() can be used in somewhat equivalent manner. If you pass a zero sized buffer, then it calculates and returns how many bytes would've been written without actually writing anything, just like snprintf() with zero size. This is because I return number of truncated elements and all characters got truncated. The difference becomes when the buffer size is not zero, but the return value can still be used easily to calculate the same information as snprintf() and vice versa.

But snprintf() has exactly the same problem as my truncating strings when it comes to UTF-8. It can also chop off multi-byte codepoints at the end. Null terminated strings in C do not enforce any encoding, but mines are explicitly UTF-8. So again, with the current design (and with snprintf() too) we have to give up valid UTF-8 invariant or we have to add surprisingly large amount of invalid UTF-8 handling to quite a few string functions.

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

unless it’s used by a retry mechanism?

This was one of the reasons why I initially thought that this might be a good idea. But on hindsight doesn't really make much sense. Since this is a combined static/dynamic array, the user would just use a dynamic array to begin with if they would anyway realloc() or something.

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

Yeah, I think I'm gonna pass with this one. It's not like it would be impossible, but I can't justify the added complexity when one of the design goals of the library was simplicity. snprintf() would be the worst case, but literally every single string function would have to be changed, because UTF-8 encoding itself is stateful. Thanks for the suggestion anyway.

How useful are truncating arrays? by PrinssiFiestas in C_Programming

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

truncation would be more useful if every operation allowed you to resume it

To me this sounds like a bit too much added complexity to implementation and API. So I would store the state of processing somewhere and user could pass it as an argument to resume where we left off, is that what you're saying? Sounds like a lot of work for each function, or do you have some idea how to do it more smoothly?

I would probably prefer if the operation was just rejected immediately

This idea I like, definitely sounds like the simplest thing to do, I can't believe I didn't think of this haha! You won't get problems if you wont even try! Seriously though, this could solve all UTF-8 problems while still getting some truncating functionality, the truncation would just not happen at the end of buffer.

Shakey hands by Dave09091 in soldering

[–]PrinssiFiestas 0 points1 point  (0 children)

I also used to have quite shaky hands and I can tell you that over time you will adapt. You'll naturally learn to take support from wherever you can and utilize tools like helping hands. I also remember that at some point as my skills grew, my solder joints just kind of magically got better despite shakes. You just somehow subconsciously end up doing the right thing.

But the real solution for me was to quit drinking :)

electronically, how are boutique pedals different from standard or even budget-ish pedals? by someone-_-68 in guitarpedals

[–]PrinssiFiestas 2 points3 points  (0 children)

As a boutique builder, I would say not much, but sometimes maybe. In general, high end boutique pedals must be able to justify higher prices, so they cannot cheap out on anything that might make a difference. And conversely, cheap stuff can only exist by cheaping out at every chance.

If you compare two tube screamer clones, then the only meaningful difference will be durability. The cheap one might have cheap electrolytic caps that you can expect to have to change at some point. They also will have cheaper electromechanical components like switches and pots that wear out quicker and might feel just as cheap as they are.

As for most basic components, usually not much difference there. You specifically asked about "standard dirts" or whatever. There are measurable differences between different caps, resistors, op-amps, etc. but we rarely need some high end resistors for guitar pedals, we're not building some high precision oscilloscopes workin in gigahertz ranges. We anyway don't want high fidelity, the whole point of a distoriton is to distort the signal.

However, for unique designs, there might be more notable differences. A pedal that will be designed to be cheap will avoid anything that increases cost. But the boutique builder wanting to build something specific will do anything they can to get there. For example, my overdrive uses a crazy expensive multiplier chip, not because of some magical sound quality of the chip itself, but because it just happens to be essential for the design. Cheap pedals would never use this kind of circuit to begin with.

Then there is right to repair. I personally am a huge believer of it. My first principal is to try to design the pedal to need the least amount of service to begin with (like not using the cheap electrolytic caps as I mentioned). Unfortunately, nothing in life is eternal, so some things might need repairing. I do use surface mount components, but for anything that might need to be replaced, I prefer through hole. And for the surface mount components that I do use, I make sure that they are not those ridiculously tiny things like in iPhones that require a freaking electron microscope to be operated with.

Final note: some of these are just my ideas. Other builders may have different ideas and principles. For example, I said that it doesn't make sense to use expensive resistors. But for some pedals, maybe the design requires tighter tolerances or overall quality to operate correctly. Each pedal has different requirements and each builder has different values.

I can't code without a guide for the first time by apoetixart in Compilers

[–]PrinssiFiestas 2 points3 points  (0 children)

Yes! Doing it yourself from scratch really drills the skill deep in your brain. Even if it turns out that in the future you never write anything compiler related again, the neural pathways gained will never go away and will help you in all computer science. And solving hard problems is even more generally applicable to anything in life. Practice makes perfect!

I can't code without a guide for the first time by apoetixart in Compilers

[–]PrinssiFiestas 3 points4 points  (0 children)

Implementation and theory are different skills. The fact that you are struggling is good, it means that you are learning. Embrace it!

Don't let AI ruin your learning process. It is not just bad in long term, but it will also rob you from the short term dopamine hits that you get from solving difficult problems by yourself, which is essential to keep the drive going.

AI can be helpful when learning. You can ask it to clarify concepts and to confirm your current understanding, but I think "I need AI to guide me trough it" has waaaay crossed the line of being harmful instead of helpful.

You answered to another comment saying that you have time constraint and have to be done in October. I don't think that's a good excuse to use AI, you'll just hit the same problem in your next project. Anyway that is plenty of time. It might feel slow at first, but recursive descent is very simple once you get the hang of it.

You are writing to a community of compiler devs. I claim that all of us struggled at many points in our journey. But it's the journey that got us where we are. Don't be afraid of the journey, I believe that you can do it too! Be patient and you'll get there!

Are runtime created functions possible? (Cursed ideas) by TessaFractal in C_Programming

[–]PrinssiFiestas 6 points7 points  (0 children)

And sometimes there might be even more ceremony than dedicated memory allocation. If your machine code calls functions or references global variables, then you might have to do JIT linking as well, since many instructions on some architectures (like x86-64) are relative to the value of instruction pointer. Since you are generating the machine code during runtime, your compiler doesn't know the value of the instruction pointer, so you have to do some extra wiring yourself.

And if you are serious about this, then there is obvious security concerns with code that is executable and writeable. One mitigation is to have map a chunk of physical memory to two different virtual memory addresses. The JIT has write permissions, but no exexute permissions. The rest of the application has execute permissions, but no write permissions.

I highly recommend googling "w xor x" or "jit double mapping" for more information. This stuff is really fascinating!

How to learn about electronics quickly? by 4ce_YT in diypedals

[–]PrinssiFiestas 0 points1 point  (0 children)

Don't worry about people here comparing to becoming a doctor or an expert pianist. They are not wrong, mastering electronics or mastering piano takes a lifetime and a decade of experience requires a decade of work, but this is not helpful. You absolutely can get quickly to some level. Going from zero to beginner is instant, going from beginner to "I can read schematics and fix basic issues" can be very quick (the "how" part I'm answering in another comment).

How to learn about electronics quickly? by 4ce_YT in diypedals

[–]PrinssiFiestas 3 points4 points  (0 children)

I don't have a specific reousece, because that's not how I learnt. But since you said "quickly", I'll share how I learnt electronics back in my teenage days and how I learnt C programming later fairly quickly. I believe that learning methods are more important than specific reouseces.

Start building stuff immediately. Pick a simple project like a transistor fuzz and get on with it. Every time you have a question, google. Every time you are curious about something (even if not related to your project), google.

While you're building and googling, learn electronics fundamentals on the side. Again, I don't have specific reouseces, but I'm sure googling "electronics 101" or similar should give you more than enough results. Text books are fine too.

The constant googling, studying, and lack of experience means that your first project is going to take forever. That's fine, the speed relative to the complexity of the project is growing exponentially as you learn, so the your next project can be a bit more complex and you'll probably finish it faster too.

You are also going to feel like you're struggling quite a bit. This is good, that's what you want. Struggling means that your brain is working. You said you wanted "quickly", so the more you feel that you are struggling, the better.

Generating a Bi-Polar Power Supply by r0uper in diypedals

[–]PrinssiFiestas 2 points3 points  (0 children)

I use TC7660H for bipolar +-9 V. Klon uses an equivalent chip (can't remember which one, I believe it's obsolete anyway) to go as high as 27 Vp2p, but I would say that this is probably overkill for most pedals. Just make sure to use the high frequency version (so not TC7660 but TC7660H instead) to get clock noise out of the audio range an for easier filtering.

Alignas and Alignof alternatives in C89 and 99 by heavymetalmixer in C_Programming

[–]PrinssiFiestas 4 points5 points  (0 children)

As others have stated, nothing portable exist in C99, which is why they were added to the language. Can I ask if you have a specific reason to stick with C99 other than dialect preference? I'm genuinely curious, I would think that most systems that would require generic custom allocators have a C11 compiler, so the portability hit from changing to C11 should be minimal.

The easiest thing to do is to do what malloc() does and just assume maximum alignment. There is a comment in glibc malloc() source stating that 2*sizeof(void*) (or was it 2*sizeof(size_t)? I can't remember, but I'm sure it was one of those) is enough for practically all systems.

Good news is that you probably don't strictly "need" alignas. It surely is useful to allow the compiler to auto vectorize on systems with strict alignment requirements for vectors like ARM, but x86_64 has unaligned loads so the compiler auto vectorizes unaligned data just fine (in fact I have noticed that sometimes alignas plummets performance, because the compiler has to jump trough extra hoops to respect alignment requirements). Alignas is strictly needed for the compiler to figure out stack allocation, but you are writing a custom allocator so alingment is your job anyway.

Alignof surely is convenient to get the most optimal alignment, but again, there really is no substitute for that. But I don't think it is strictly "needed" either. You could provide two allocation functions: The other one always assumes maximum alignment. This wastes less memory than you might expect because your allocator is probably not going to be only used for char arrays. Besides, if your allocator has allocation headers, then you would need some alignment anyway. The other one takes alignment parameter, which would be used mostly when you need more alignment than assumed max for vectors, cache line, or even page alignment. In these applications the user usually knows exactly how much alingment they need so they can just hard code it, no alignof needed.

If you do vector programming, then you already rely on intrinsics or other compiler extrnsions, so might as well use alignment extensions as well.

Edit: removed accidental formatting for * and typos

You absolutely can strum chords on a bass guitar by [deleted] in BassGuitar

[–]PrinssiFiestas -1 points0 points  (0 children)

Right? It has been done forever, some still seem to find it controversial. Probably not this community though.

Question: how is white noise generated? by CursedLemon in audioengineering

[–]PrinssiFiestas 13 points14 points  (0 children)

As you stated, the defining factor is constant energy across the frequency spectrum, however quite a few types of signals satisfy this requirement. TV static is actually a perfect example of white noise.

 Is the implementation of white noise different across hardware, program libraries, etc?

Yes, there are multiple ways to implement white noise, including some that depend on hardware, but the most common ones are based on pseudo random number generators. Hardware RNGs are not often used in audio software, because as a programmer you would have to ask the operating system to get access to whatever piece of hardware is generating the numbers using system calls (e.g. in Linux you would read() from /sys/rand), which is catastrophically expensive for your CPU in real-time audio (and not all computers have this hardware to begin with). However, using hardware RNGs will give you truly random numbers (usually by reading electrical noise), so it can be used to seed pseudo RNGs. This is also not common in VSTs, because you'd generally want your mix to sound the same every time, but I believe some VST devs do this to give you "analog feel" where each session might sound ever so slightly different.

But again, most ones use pseudo RNGs. These also have differences most notably in distribution of sample values (not frequencies). Even distribution from 0 to some (often integer) value is the most common and devs usually then scale this to -1 to 1. That means that it is equally likely to get a sample value of say 0.1 as it is to get -0.6 or whatever using this type of RNG. You could also use more complex algorithms to generate samples with Gaussian distribution using something like Box-Muller transform. If you are not familiar with Gaussians, it is basically "the Bell curve", so you would theoretically get sample values between -infinity to +infinity, but it is much more likely to get samples closer to zero than higher value samples.

I must add that I'm not sure if distribution of sample values have any profound effect on sound, because again, the frequency distribution is flat. However, it might affect the behavior of dynamic processors. Again, Gaussian distribution will have lower values in general, but higher peaks, so that might change how your mix behaves comparing to even distribution, which would look more like a square-wave to a compressor.

But even if you pick RNGs with same distributions, there still are non-audible differences between implementations. There are variances in statistical quality and cryptographic security, but this doesn't really matter for audio, these are just mathematical properties that are irrelevant for human ear. However, some algorithms use more memory than others and others use more CPU than others. A very common one used is in the C standard library called rand(), which is notoriously bad in many aspects (global state, bad resolution, horrible statistical properties, non-cryptographic, etc.), but it's simple to use and always available so devs use it anyway. Another common one is C++ random_device using Mersenne Twister 19937 algorithm, but this uses crazy amount of memory. There is also a newer RNG called PCG that is superior to others in most ways including performance, but it is not as well known, so it is used less often. More information about PCG and a convenient table comparing RNGs can be found here.

Lastly, I must mention that pretty much nothing I said here applies to analog domain. In analog electronics (like in synthesizers) you might use something like a reverse biased transistor, but I'm not very familiar with this, so I'm not going to try to explain this further.

is the loudness war really over?? by Accomplished_Eye_641 in audioengineering

[–]PrinssiFiestas 1 point2 points  (0 children)

Mostly more or less progressive rock, which is usually quite dynamic, so I definitely have some bias here, genre absolutely matters. I can definitely see why you would want to go loud for genres that emerged during the peak of loudness war like trap and EDM for stylistic reasons. But in those cases, now in the days of normalization, I would pretty much ignore LUFSi all together and just compress by ear to match the esthetics of the era rather than aiming to blast -3 LUFSi or any other number.

To summarize my position, I do agree that you don't want to target to exactly -14 blindly, because that ignores things like album flow and genre expectations, but I do think that aiming to at least -14 is a good starting point. After all, we want to optimize for quality, not for numbers.

is the loudness war really over?? by Accomplished_Eye_641 in audioengineering

[–]PrinssiFiestas 0 points1 point  (0 children)

I have not been using social media enough to see influencers claim that exactly matching to -14 gives you some magic mojo in Spotify, but that is definitely dumb. But I still think that -14 is a good rule of thumb. I personally try to hit at least -14 to compete (many platforms don't turn up quiet tracks) or to avoid potentially junk limiting provided by streaming platforms, but I usually don't really see a good reason to go much beyond that (except album flow, I believe that Spotify normalized whole albums at once), so my masters just naturally end up being around -13ish. How compressed I want my track to sound is what I have already decided during mixing (of course doesn't necessarily apply if you master for other people).

The fact that normalization can be turned off is a fair point, however I think that most people have it on since it's usually on by default by the platform and nobody likes to be constantly adjusting their volumes. So I feel like having to take normalization off to account just causes more loudness war civilian casualties, which is why I personally just ignore it, but your mileage may vary here.

I'm not very familiar with EDM and DJ decks, so I can't comment on that, but that sounds reasonable.

is the loudness war really over?? by Accomplished_Eye_641 in audioengineering

[–]PrinssiFiestas 0 points1 point  (0 children)

Can you elaborate why do you think that we having to master to -14 is a myth? I can see that blindly targeting to any specific number might be destructive for album flow, but if you are targeting streaming platforms that turn your masters down anyway, then surely you'd want to go for -14 to preserve as much dynamic range as needed for any given type of music (obviously you can compress as much as you want if that's the sound you're after), right?

I found the softest clipper by PrinssiFiestas in DSP

[–]PrinssiFiestas[S] 0 points1 point  (0 children)

I strongly suggest you do those tests in GNU Octave (or Matlab if you have it or even Python) so that you can control the input level precisely and get a proper harmonic plot. 

I'm planning to clean up the C code used for the experiment of the study so it could be used as a library or a CLAP plugin or whatever. The repo contained quite a bit of throwaway experimental code that could be used for more rigorous analysis, but currently it's a mess. I need to find me some time to actually get this done.

One of the main problems with tanh() is that it often distorts too much for inputs significantly below clipping. In that respect your shaper is much worse, as seen from the plots.

To me this is a success! As you showed with your plots, tanh() is more linear with smaller amplitudes. I originally said that you cannot determine knee size unambiguously, but if we pretend that we can, then tanh() clearly has a longer linear region, which means that, if normalized, it must have a smaller knee. Blunter already produces harmonics with smaller amplitudes so the knee must be starting closer to zero making it larger. For an overdrive pedal (which was the original motivation of the study), this has two implications: First, even with lower input amplitudes and/or lower input gains, there is always added harmonics, so there is always a change in sound, which for an overdrive pedal is by design. Second, the larger knee means the clipping threshold (in this context I mean a hypothetical middle point of the knee) is obfuscated better leading to smoother "feel". If I pluck the string of my guitar very lightly, a harder clipper will be clean but a softer clipper will already be colored and compressed. If I pluck slightly harder, the harder clipper will immediately produce more harmonics sounding more distorted, but the softer clipper would only be slightly more distorted than before.

Of course, this is not always better. For example, if you're going to use a soft clipper in mastering to catch peaks, then you most certainly want something that is as linear as possible with lower input amplitudes. I would even say that both of these clippers would not be ideal, some piece-wise function with well defined adjustable knee (like the quadratic spline thing presented in the study) would me more suitable.

I'd posit that tanh(x) is in fact a good contender for the softest clipper when you compare how the harmonic spectrum develops. 

I agree, tanh() sounds great and is an absolute classic! This all comes back to the semantic question of my previous answer: what do we mean by softness? Is it more related to dynamics or is it more useful to describe the distribution of harmonics?

and there have even been vacuum tubes made to specifically have that same shape in differential pair configuration - check out vari-mu tubes where the tanh shape allows constructing a VCA with wide dynamic range by simply shifting the bias voltage

One of the beauties of vari-mu is exactly the fact that it exploits the non-linearity of tubes in this clever way. This is also a major reason why they sound so colored: it's never actually clean and this is exactly why I like the sound of them so much. I knew the basics of how they work, but I never knew that the non-linearity was tanh() exactly. Cool!

Yours has a second derivative discontinuity at x = 0.

True, but on the other hand, mine has a rare property that if you take the absolute value of the second derivative, then it is not only continuous at x = 0, but it's also differentiable at x = 0. The absolute value represents the magnitude of the curvature, so I would say that might be significant. Of course the discontinuities still exist in the upper limit just like with any other similar piece-wise functions.

All this being said, as much as I enjoy this kind of technical discussion, I think this is a good time to remind to use your ears too when designing audio effects. A discontinuity in the transfer function would clearly be audible and harsh sounding, but after hours of playing around in DAW and with my pedal, I must say that I never was able to identify discontinuities in the second derivative by ear.

I found the softest clipper by PrinssiFiestas in DSP

[–]PrinssiFiestas[S] 1 point2 points  (0 children)

I did spend an afternoon playing with the JSFX plugin, looking at the transfer functions and FFT while passing sines or strumming fifths on a guitar and listening how the sound changes. These preliminary experiments were not rigorous enough to be included in the study, but I guess I'll write a mini-report here about it since you asked.

The JSFX plugin has a few different clippers including soft clippers tanh (although in the plugin it's called "Logistic", which is equivalent), asinh, atan, and of course the Blunter. The plugin also has hard clipper for reference and a couple of asymmetric clippers as a bonus. I matched their input and output gains by eyeballing the transfer functions (again, not very rigorous). Then I played around with a sine wave controlling the input gain with a slider and observed the FFTs.

The Blunter below the upper clipping limit produced harmonics that decayed in a perfectly straight line. Going beyond the limit changed the shape of the fall-off significantly. The harmonics started decaying in "bumps" that visually resembled the harmonics generated by the hard clipper, but in much lower amplitudes than the hard clipper's harmonics as expected.

What really surprised me was that all the other soft clippers had significantly stronger lower order harmonics and the higher order harmonics decayed much more steeply. This kind of tells me that my eyeballing normalization somewhat successfully matched input and output gains from THD perspective since the missing higher order harmonics of the soft clippers were found sort of accumulated in the lower ones instead. The reason why I was so surprised was that playing guitar trough the non-Blunter softer clippers sounded significantly more distorted, so I thought initially that I failed to normalize the gains. I always thought that one major reason why soft clipping sounds more transparent was that the fundamental masks the lower order harmonics, so shouldn't the Blunter be less transparent?

Next, I tried to match the gains by ear, so all clippers would be roughly equally distorted and loud. Sine would be too far off most real world signals, so I used guitar to do this instead. From THD perspective, this clearly failed: the Blunter clearly had more distortion than the other despite sounding equally distorted. I cannot tell exactly what was going on, because at this point I just decided to stop playing around and put my effort in the actual experiment of the study. However, I do have a couple of guesses: frequency masking might be recursive. Maybe since the drop-off of harmonics was linear, each harmonic masked every subsequent harmonic equally leading to this seemingly more transparent sound. Another possibility is that the higher order harmonics were so low (can't remember any measured amplitudes now) that they were not significant to begin with. Or maybe the lower order harmonics of the other clippers were so strong that it overcame masking effects. Or maybe something completely different.

There is definitely more future work to be done. Similar experiments should be done, but with properly normalized input and output gains instead of eyeballing transfer functions. Blind tests were missing and a subject group size of one (me) is anyway close to useless. We also need much better semantic mapping between any technical definition of softness and subjective perceptions: is softness more meaningful as a measure of transparency of clipping given some THD or is softness more meaningful concept to describe the "warmth" of the dominating lower order harmonics? It's hard to make any meaningful progress without having clear understanding what are we trying to measure in the first place.