---
# System prepended metadata

title: 開發紀錄(week3)

---

# 開發紀錄(week3)


### Note
---
- f : Hz (一秒震盪幾次)
- f<sub>s</sub> : 取樣頻率 (一秒取樣幾次)
- T : 週期 cycle time : sec (一次震盪幾秒)
- ω = 2πf = 2π/T = 角度差/週期 (一秒走多少角度)
- sin(ωt+θ) = sin(2πf * t+θ) = sin(2πf * n/f<sub>s</sub>+θ)
    - t為時間
    - n為index(第幾個angleIncrement)
    - sin(一秒走多少角度*一次取樣花幾秒+θ=一次取樣走多少角度+θ)

<br>

- 
    - 下兩圖的x,y軸是相對應的, 事實上x軸並非實數軸, 而是度數
    - sin(x)值為對應的y值
    - sin(currentAngle) = sin(x)
![link text](https://www.researchgate.net/publication/341812787/figure/fig1/AS:897790007836673@1591061226081/The-unit-circle-used-for-deriving-sine-and-cosine-functions.png)
![link text](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/Sine.svg/885px-Sine.svg.png)

<br>

- angleIncrement: 2πf * 1/f<sub>s</sub> = 一秒走多少角度*一次取樣花幾秒 = 一次取樣走多少角度
    - 由getSampleRte()取得f<sub>s</sub>
```C++
void SynthVoice::startNote (int midiNoteNumber, float velocity, juce::SynthesiserSound* sound, int currentPitchWheelPosition){
    noteMidiNumber = midiNoteNumber;
    frequency = juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber);
    currentAngle = 0.f;
    angleIncrement = frequency / getSampleRate() * juce::MathConstants<float>::twoPi;
    tailOff = 0.0;
}
```

<br>

- 
    - numSamples : 是一個block有多少存取點, 每次以block為單位回傳處理好的值, 所以for loop會執行一個block的次數
    - Sin(currentAngle)的currenAngle會在每一次跑for loop時增加一個angleIncrement=一秒走多少角度*一次取樣花幾秒 &rarr; 一次取樣走多少角度
```C++
void SynthVoice::renderNextBlock (juce::AudioBuffer<float> &outputBuffer, int startSample, int numSamples){
    if (tailOff > 0.0){
        for (int i = startSample; i < (startSample + numSamples); i++){
            float value = std::sin(currentAngle) * level * tailOff;
            outputBuffer.addSample(0, i, value);
            outputBuffer.addSample(1, i, value);

            currentAngle += angleIncrement;
            tailOff *= 0.99;

            if (tailOff <= 0.05){
                clearCurrentNote();
                angleIncrement = 0.0;
                level = 0.0;
                break;
            }
        }

    }
    else{
        for (int i = startSample; i < (startSample + numSamples); i++){
            float value = std::sin(currentAngle) * level;
            outputBuffer.addSample(0, i, value);
            outputBuffer.addSample(1, i, value);

            currentAngle += angleIncrement;
        }
    }
}
```

<br>

### Wave shape
---
![link text](https://quorumlanguage.com/media/dsp/waveforms.png)

<br>

### Sine wave
---
```
for (int i = startSample; i < (startSample + numSamples); i++){
    float value = std::sin(currentAngle) * level * tailOff;
    outputBuffer.addSample(0, i, value);
    outputBuffer.addSample(1, i, value);

    currentAngle += angleIncrement;
    tailOff *= 0.99;
}
```


<br>

### Triangle wave
---
- 
    - currentAngle < 1/2π: equation=2/π * x  
    - 1/2π < currentAngle < 3/2π: equation=-2/π * x + 2
    - currentAngle > 3/2π: equation=2/π * x - 4
```
for (int i = startSample; i < (startSample + numSamples); i++){
    if (currentAngle > juce::MathConstants<float>::twoPi){
        currentAngle -= juce::MathConstants<float>::twoPi;
    }
    if(currentAngle < 1/2 * juce::MathConstants<float>::pi{
	float value = 2 / juce::MathConstants<float>::pi * currentAngle * level * tailOff;
    }
    else if(1/2 * juce::MathConstants<float>::pi < currentAngle < 3/2 * juce::MathConstants<float>::pi){
	float value = (-2 / juce::MathConstants<float>::pi * currentAngle + 2) * level * tailOff;
    }
    else if (currentAngle > 3/2 * juce::MathConstants<float>::pi){
	float value = (2 / juce::MathConstants<float>::pi * currentAngle - 4) * level * tailOff;
    }
    outputBuffer.addSample(0, i, value);
    outputBuffer.addSample(1, i, value);

    currentAngle += angleIncrement;
    tailOff *= 0.99;
}
```

<br>

### Sawtooth wave
- equation=1/π * x - 1
---
```
for (int i = startSample; i < (startSample + numSamples); i++){
    if (currentAngle > juce::MathConstants<float>::twoPi){
        currentAngle -= juce::MathConstants<float>::twoPi;
    }
    float value = (1 / juce::MathConstants<float>::pi * currentAngle - 1) * level * tailOff;
    outputBuffer.addSample(0, i, value);
    outputBuffer.addSample(1, i, value);

    currentAngle += angleIncrement;
    tailOff *= 0.99;
}
```
<br>

### Square wave
---
```
for (int i = startSample; i < (startSample + numSamples); i++){
    if(std::sin(currentAngle) > 0){
	float value = 1 * level * tailOff;
    }
    else if(std::sin(currentAngle) < 0){
	float value = -1 * level * tailOff;
    }
    outputBuffer.addSample(0, i, value);
    outputBuffer.addSample(1, i, value);

    currentAngle += angleIncrement;
    tailOff *= 0.99;
}
```
<br>

### Settings
- 每次開新專案都要Debug一次




