Как делается звук аккордеона
Сценарий развития звука аккордеона.
В тексте, приведённом ниже, сделаны искусственные разрывы посередине длинных
строк. Иначе строки с длинными последовательностями символов не видны на
страницах сайта проза.ру. В действительности этих разрывов нет.
В зависимости от значения глобальной переменной ARE3 тембр звука может быть различным. Помимо приведённых в сценарии трёх вариантов, строки, создающие профиль звука, можно задавать напрямую, то есть, указывая значения A31r$, A32r$, A31r$ в партитуре. Партитура это текстовый файл, в котором записаны в столбик частоты, длительности звуков, а также мнемонические указания, которые процессом управляют.
В программе Трио используется по-периодный метод синтеза музыкального звука.
Это значат, что в момент начала звука выполняется весь сценарий целиком,
В промежутках между периодами - только часть с отрицательным значением Case,
а основное время, когда период начался, но ещё не закончился, выполняется быстрое вычисление амплитуды сэмплов.
Для аккордеона это делается так -
If AU3 = 0 Then A3 = 0 Else A3 = AA3 * FNSPL(Arr$, X) 'A3 take
___________
Case 7 'accordeon tembr => Ar=1(0) 2 3
MU2 = 0: AU2 = 1: DU2 = 30.999: mod2 = 2
If FS < 260 Then DU2 = Int(FS / 8.7) + 0.999
If UD3c > 0 Then DU2 = UD3c: 'V = DU2 - Int(DU2): If V < 0.1 Then UD3b = 1 + V
MU3 = 0: AU3 = 3: DU3 = DU2
Select Case ARE3: Case 0, 1
'>>>>="_1_2_3_4_5_6_7_8_9_0 _1_2_3_4_5_6_7_8_9_0_1_2_3_4"
A31r$ = "504501455050505050 505050505579555050504521455050" 'norm
A32r$ = "504501455050505050 505050505599555050504501455050" '-3 15 -21 L=24
A33r$ = "504521455050505050 505050505599555050504501455050": Case 2
'>>>>="_1_2_3_4_5_6_7_8_9_0 _1_2_3_4_5_6_7_8_9_0_1_2_3_4"
A31r$ = "504501014550505050 505050505579795550505045212145" 'quiet
A32r$ = "504501014550505050 505050505599995550505045010145" '-3 15 -21 L=24
A33r$ = "504521214550505050 505050505599995550505045010145": Case 3
'>>>>="_1_2_3_4_5_6_7_8_9_0 _1_2_3_4_5_6_7_8_9_0_1_2_3_4"
A31r$ = "504501459505950505 950595055579555050504521455050" 'sharp
A32r$ = "504501456535653535 653565355599555050504501455050" '-3 15 -21 L=24
A33r$ = "504521459505950505 950595055599555050504501455050": End Select
Apm$ = "5051525045465046515 55047504751535057": Dpm = 1
RR(0) = 0: V = FNRR(0, 1006.4): V = FNRR(0, 2006.4): V = FNRR(30, -9)
Case -7: Arr$ = FNRE$((FNTIM(9, T) + FNTIM(13, T)) / 2, 3)
If UD3b > 0 And DU2 < 1.1 Then DU2 = UD3b: DU3 = UD3b: UD3b = 0
_____________
Используемые подпрограммы
1. РОТАЦИЯ СТРОК
______________
'======== 3 to one for line rotation
Public Function FNRE$(AM As Double, K As Integer)
Dim r$, R1$, R2$, R3$, M$, A As Double, DR1 As Double, DR2 As Double, DR3 As Double
A = AM: r$ = ""
If A < -1 Then A = -1
If A > 1 Then A = 1
Select Case K
Case 1: R1$ = A11r$: R2$ = A12r$: R3$ = A13r$
Case 2: R1$ = A21r$: R2$ = A22r$: R3$ = A23r$
Case 3: R1$ = A31r$: R2$ = A32r$: R3$ = A33r$
End Select
Do While Len(R2$) > 1
DR2 = Val(Mid$(R2$, 1, 2)): If DR2 = 0 Then DR2 = 50
DR1 = Val(Mid$(R1$, 1, 2)): If DR1 = 0 Then DR1 = DR2
DR3 = Val(Mid$(R3$, 1, 2)): If DR3 = 0 Then DR3 = DR2
If A > 0 Then DR = DR3 * A + DR2 * (1 - A) Else DR = -DR1 * A + DR2 * (1 + A)
M$ = Str$(Int(DR + 0.5)): If Len(M$) > 2 Then M$ = Mid$(M$, 2, 2)
r$ = r$ + M$
R1$ = Mid$(R1$, 3): R2$ = Mid$(R2$, 3): R3$ = Mid$(R3$, 3): Loop
If r$ = "" Then FNRE$ = "50" Else FNRE$ = r$
End Function
__________________
2. Периодическая функция, создающая ТРЕУГОЛЬНУЮ ФОРМУ
'=============== \/\/\/ low frequency vibration +-1 with F on Time
Public Function FNTIM(F As Double, Time As Double) As Double
Dim T As Double
T = Time * F: T = T - Int(T): If T < 0.25 Then T = 0.5 - T
If T > 0.75 Then T = 1.5 - T
T = (T - 0.5) * 4: FNTIM = T
End Function
'==================
3. Функция для быстрого вычисления АМПЛИТУДЫ СЭМПЛОВ
'====== spline interpolation
Public Function FNSPL(A$, X As Double) As Double 'spline interpolation As Long
Dim L As Double, Nr As Integer, B As Double, B1 As Double, B2 As Double, ZZ As Double
L = Len(A$) / 2: If L < 1 Then FNSPL = 0: Exit Function
L = X * L / 2: Nr = Int(L): L = (L - Nr) * 2 - 1: Nr = Nr * 2 + 1
B = Val(Mid$(A$, Nr, 2))
If Nr = 1 Then B1 = 50 Else B1 = (Val(Mid$(A$, Nr - 2, 2)) + B) / 2
If Nr = Len(A$) - 1 Then B2 = 50 Else B2 = (Val(Mid$(A$, Nr + 2, 2)) + B) / 2
B2 = (B2 - B1) / 2: B1 = B2 + B1 'B2=(-)/2 B1=(+)/2
ZZ = B1 + B2 * L: ZZ = ZZ + (B - B1) * (1 - L * L)
FNSPL = (ZZ / 50 - 1)
End Function
______________________
Полностью с исходниками программы
можно ознакомиться тут - http://yadi.sk/d/4YB1q5Hj3NLAn4
Свидетельство о публикации №222102300010