Как делается звук аккордеона

  Видео на эту тему смотрим здесь - https://youtu.be/CxyDkKNKpGs
  Сценарий развития звука аккордеона.
  В тексте, приведённом ниже, сделаны искусственные разрывы посередине длинных
строк. Иначе строки с длинными последовательностями символов не видны на
страницах сайта проза.ру. В действительности этих разрывов нет.

В зависимости от значения глобальной переменной 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


Рецензии