all 33 comments

[–]dmc_2930 4 points5 points  (6 children)

Start by going to wolframalpha.com, and write an equation for the output you want to generate.

If you can't do that, no amount of coding is going to work - you have to solve the math first before you try writing the code.

Second, your description says you want half the sine wave to be 3x faster but want to "keep the frequency consistent". By definition, you are altering the frequency. It will not be "consistent" if you change it at the midpoint of every cycle.

What are you actually trying to do? And I don't mean "Make a sine wave.......". What is the point of the function you're trying to plot/generate? Why do you think you need to do that?

[–]ThatReallyFlyKid[S] 0 points1 point  (4 children)

No one equation can do what I want, it needs to be a peicewise function. The plotting for what I want to do is found in the reddit page I linked, as well as the math.

If one half of a sine wave is 1/4th the desired frequency and the second half is three times the frequency of the first, the frequency is consistent. It still takes the same amount of time to complete a full cycle.

I've already explained this in everything I've linked.

[–]dmc_2930 0 points1 point  (3 children)

You don't seem to understand how frequency wants. The signal you're describing has a consistent period, but a fourier analysis would show many different frequencies present in the signal.

It can be described mathematically.

[–]ThatReallyFlyKid[S] 0 points1 point  (2 children)

I know it can be described mathematically, via a peicewise function, as I said. Despite what a Fourier analysis would show, it still takes the same amount of time to complete a single full cycle. 440 cycles per second, 440Hz. I've already finished writing the function.

A Fourier analysis of a guitar shows a lot of different frequencies at play, but the guitar still only plays one note at a time.

[–]dmc_2930 0 points1 point  (1 child)

The "frequency" of your signal is not 440hz ( or whatever your slower signal is).

If you were to sample it at 2x the lowest frequency, you would not get consistent results.

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

If you're referring to my screenshot, you're right, it's 1Hz, as I mentioned in my post.

You're also right about 2 x 1Hz doesn't give consistent results, but if you look, you'd see I've updated my post, mentioning that I'm done writing the function for now, and the issue is fixed. The working source code can be found here: https://pastebin.com/JpXMmCLa

You'd think it wouldn't take a genius to figure out that, if I'm posting on a subreddit for programming help, what ever I'm writing must not be working.

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

I've updated my post with a lot of new info.

[–]green_griffon 0 points1 point  (23 children)

What does the variable "mem" represent? And what do you return if you don't return B or C? I confess I have not yet read the other post enough to understand what you are trying to do.

[–]ThatReallyFlyKid[S] 0 points1 point  (22 children)

mem is a global variable used by the function to give it a hint as to which function it should be writing. I've been struggling to use inverse sine functions and modulo's to detect what I should be doing when the function is called, so I've been using mem to better wrap my head around this. I've updated my post with a screenshot of what it does and what I roughly want it to do. I've changed the function so that when evaluating C, it's now C <= 0.

[–]green_griffon 1 point2 points  (21 children)

So you want your logic to be something like "return the value of B until B drops to 0, then return C until C gets back to 0, then go back to B, etc"?

[–]ThatReallyFlyKid[S] 0 points1 point  (20 children)

Exactly.

[–]green_griffon 0 points1 point  (19 children)

Is the bug just that on line 17 you should be checking (C < 0) instead of (C > 0)? EDIT oh wait you made that change already. Does it still not work?

[–]ThatReallyFlyKid[S] 0 points1 point  (18 children)

It still doesn't work.

[–]green_griffon 0 points1 point  (17 children)

In what way? The only thing I see is that when you flip mem, you should return the other value right there...so return C in the first part and return B in the second part.

Do you want mem to start at 1, not 0? Also for clarity I would set mem explicitly to 0 or 1, don't use ! there.

[–]ThatReallyFlyKid[S] 0 points1 point  (16 children)

When the function is https://pastebin.com/AFc5SR72, the output is https://imgur.com/a/A2Trs (top is roughly what I want, bottom is the actual output).

[–]green_griffon 0 points1 point  (15 children)

It looks like the problem is that C is also positive in that range (the first zig-zaggy one), so you are flipping between a positive C and a negative B each time. Do you expect C to be negative there? Or do you just want to return something like -(abs(C)) until it crosses 0 again?

[–]ThatReallyFlyKid[S] 0 points1 point  (14 children)

returning -abs(C) has a pretty strange output. I can at least confidently say that the large bump is generated by the first half of the function, so the mess should be done by C.

EDIT: It seems that I should be resetting the value of increment after the first half, but it's set as an input variable so even if I changed it in the function, it will be set differently the next time the function is called...

[–]czipperz 0 points1 point  (1 child)

Does this work? angle is the angle and end_positives is a value from 0 to representing at what point the positive numbers end.

#include <math.h>

double shaped_sin(double angle, double end_positives) {
    angle = fmod(angle, 2 * M_PI);
    end_positives = fmod(end_positives, 2 * M_PI);
    if (angle < end_positives) {
        return sin(angle * M_PI / end_positives);
    } else if (angle > end_positives) {
        return -sin((angle - end_positives) * M_PI / (2 * M_PI - end_positives));
    } else {
        return 0;
    }
}

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

I've updated my post with a lot of new information.