Pregunta

I am trying to create the custom wave signals using iOS When adding the second for loop to create, it works to create the impulse between the interval 0.8T and 0.9T m which T is the period.

When I try add the third for loop to create one , it creates a weird signals with convex hyperbola after period 0.7T instead of generating a new impulse.

Would you please tell me which I shall modify or reset the buffer variable so that I can generate multiple impulses ?

The below is my code

// Fixed amplitude is good enough for our purposes
const double amplitude = 1.0;

// Get the tone parameters out of the view controller
ToneGeneratorViewController *viewController =
(ToneGeneratorViewController *)inRefCon;
double theta = viewController->theta;
//double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;
double theta_increment = viewController->sampleRate / viewController->frequency;

( sampleRate = 44100; , frequency = 44.44 )

const int channel = 0;
    Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

    float squareIndex = 0.0;
    //Generate the samples//
    for (UInt32 frame = 0; frame < inNumberFrames; frame++)
    {
        float k =0.0;
        float y = 34.0/75.0;
        if( fmodf(squareIndex, theta_increment)/theta_increment < y) {
            k = 1.0;
        } else {
            k = 0.0;
        }
        buffer[frame] = k * amplitude;
        squareIndex += 1.0;
        if(squareIndex >= theta_increment) squareIndex-=theta_increment;
        viewController->theta = theta;
    }


    for (UInt32 frame = 0; frame < inNumberFrames; frame++)
    {
        float k =0.0;
        float z = 0.8;
        float y = 0.9;
        if( z < fmodf(squareIndex, theta_increment)/theta_increment < y) {
            k = 0.0;
        } else {
            k = 1.0;
        }
        buffer[frame] += k * amplitude;
        squareIndex += 1.0;
        if(squareIndex >= theta_increment) squareIndex-=theta_increment;
        viewController->theta = theta;
    }


    for (UInt32 frame = 0; frame < inNumberFrames; frame++)
    {
        float k =0.0;
        float z = 0.6;
        float y = 0.7;
        if( z < fmodf(squareIndex, theta_increment)/theta_increment < y) {
            k = 0.0;
        } else {
            k = 1.0;
        }
        buffer[frame] += k * amplitude;
        squareIndex += 1.0;
        if(squareIndex >= theta_increment) squareIndex-=theta_increment;
        viewController->theta = theta;
    }
¿Fue útil?

Solución

Since we don't see buffer allocation in the provided code, I would assuming that the buffer has sufficient size to hold all samples (otherwise buffer overflow could cause all sorts of undefined behaviors).

With the code provided, you should realize that in the loops, the expressions

if( z < fmodf(squareIndex, theta_increment)/theta_increment < y) {

are evaluated from left to right as:

if( (z < fmodf(squareIndex, theta_increment)/theta_increment) < y) {

Let's look at the second loop to illustrate the effect:

so long as squareIndex is less than0.8*theta_increment`, the subexpression

(z < fmodf(squareIndex, theta_increment)/theta_increment)

evaluates to false which, after numerical promotion, is less than y=0.9, so the overall expression is true (so k=0). Once squareIndex becomes more than 0.8*theta_increment

(z < fmodf(squareIndex, theta_increment)/theta_increment)

becomes true which, again after numeric promotion, is more than y=0.9, so the overall expression becomes false (so k=1). The loops then generate the following curves:Before fixes

where from top to bottom you have the first, second and third loop, followed by the combined waveform.

To fix this you can change the conditions to:

 float t = fmodf(squareIndex, theta_increment)/theta_increment;
 if (z < t && t < y) {
   k = 1.0;
 } else {
   k = 0.0;
 }

Which should then generate the following waveform: enter image description here

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top