# 開發紀錄(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)


<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=一秒走多少角度*一次取樣花幾秒 → 一次取樣走多少角度
```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
---

<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一次