Recent Changes - Search:

Главная страница

Проекты

Статьи

Домашний WiFi роутер

Архив проектов

Загрузки

GitHub

SourceForge

edit SideBar

Patch

Как описание Patch'а переводится в значения регистров LA32

Wave Generator

Structure of Partial

Согласно www.polynominal.com у MT-32 имеется 13 возможных вариантов использования partials. В firmware v1.0.7 описание Partial Structure находится в массиве uint16_t, находящимся по адресу 669Eh. Вот так он выглядит в двоичном представлении.

#MSB LSBDescription 
 [15:14][13:13][12:12][11:10][9:9][8:8] [7:6][5:5][4:4][3:2][1:1][0:0]  
 -RI[12:12][11:10][9:9]WG -RI[4:4][3:2][1:1]WG  
100000100 00000000SS mix partial 1-2
200100100 00000000SS mix partial 1 + Ring modulator
300000100 11000001PS mix partial 1-2
400100100 11000001PS mix partial 1 + ring modulator
510100101 00000000SP mix partial 1 + ring modulator
611000101 11000001PP mix partial 1-2
710100101 11000001PP mix partial 1-2 + ring modulator
 
800001100 00001000SS each partial is send to left right
911001101 11001001PP each partial is send to left right
 
1000100100 00100000SS partial are ringmodulated then out
1100100100 11100001PS partial are ringmodulated then out
1210100101 00100000SP partial are ringmodulated then out
1310100101 11100001PP partial are ringmodulated then out

Каждый байт отвечает за один partial: LSB - за partial1, MSB - за partial2. Назначение полей в этих байтах совпадают.

[7:6] - WG mode extension: 00 - SYN, 10 - PCM with Ring Modulation, 11 - PCM;
[5:5] - ring modulation. Для partial2 бит RI ([13:13]) должен быть сброшен (FixMe: кажется в таблице все не так);
[4:4] - reserved2;
[3:2] - partial L/R channel: 0 - partial1 mix, 1 - partial2 mix, 2 - partial1 left, 3 - partial2 right;
[1:1] - reserved1;
[0:0] - WG mode: 0 - SYN, 1 - PCM.

Partial Structure отвечает за:

  • режим работы WG (генератора тона): синтез или сэмплирование;
  • распределение partials по каналам: левый или правый (используется для вычисления panpot);
  • наличие Ring Modulation между partials.

Биты [7:6] в PCM режиме напрямую копируются в регистр WG_SETUP синтезатора LA32. По какой-то причине, для partial2 при включенном Ring Modulation их значения должны быть 0b10 вместо 0b11.

PCM

Что используется

  • Timbre Temp Memory, Common parameter, Structure of partial
  • Timbre Temp Memory, Partial Parameter, WG PCM WAVE
  • Rhythm Setup, PANPOT или Patch Temp, PANPOT
  • Rhythm Setup, REVERB SWITCH или Patch Temp, REVERB SWITCH

На что влияют

  • WG_SETUP
  • WG_PCM_SAMPLE
  • WG_PCM_LEN

Synth

Что используется

  • Timbre Temp Memory, Common parameter, Structure of partial
  • Timbre Temp Memory, Partial Parameter, WG WAVEFORM
  • WG_PULSE_WIDTH - Timbre Temp Memory, Partial Parameter, WG PULSE WIDTH
  • WG_PW_VELO_SENS - Timbre Temp Memory, Partial Parameter, WG PW VELO SENS (0..14, -7..+7)
  • Rhythm Setup, PANPOT или Patch Temp, PANPOT
  • Rhythm Setup, REVERB SWITCH или Patch Temp, REVERB SWITCH
  • VELOCITY - MIDI Velocity (0..127)

На что влияют

  • WG_SETUP
  • WG_PULSE_WIDTH
WG_PULSE_WIDTH = USAT8( ((VELOCITY - 64) * (WG_PW_VELO_SENS - 7)) + MAP_PULSE_WIDTH[WG_PULSE_WIDTH] )

USAT8(a, b) - насыщение в uint8_t.

Pitch

Что используется

  • NOTE - MIDI Note
  • WG_PITCH_KEYFOLLOW - Timbre Temp Memory, Partial Parameter, WG PITCH KEYFOLLOW
  • WG_PITCH_COARSE - Timbre Temp Memory, Partial Parameter, WG PITCH COARSE
  • WG_PITCH_FINE - Timbre Temp Memory, Partial Parameter, WG PITCH FINE
  • KEY_SHIFT - Patch Temp Area, KEY SHIFT
  • FINE_TUNE - Patch Temp Area, FINE TUNE
  • WG_SETUP[7:7] - Timbre Temp Memory, Common parameter, Structure of partial
pitch_note = (NOTE + 12) / 12
pitch_octave = (NOTE + 12) % 12


epitch_base = MAP_PITCH[pitch_note]; // высота тона
epitch_base += pitch_octave * 0x1'000; // каждая октава удваивает частоту тона (см. примечание)
epitch_base += 0x6'000; // какая-то коррекция

epitch_base = (epitch_base * MAP_KEYFOLLOW[WG_PITCH_KEYFOLLOW] / (2 * 0x1000);

epitch_base += MAP_COARSE[WG_PITCH_COARSE]; // грубая подстройка тона в настройках Partial (полутоны)
epitch_base += MAP_FINE[WG_PITCH_FINE];  // тонкая подстройка тона в настройках Partial (центы)

epitch_base += MAP_COARSE[KEY_SHIFT + 12]
epitch_base += MAP_FINE[FINE_TUNE]

PCM

  • WG_PCM_WAVE - Timbre Temp Memory, Partial Parameter, WG PCM WAVE
epitch_base += MAP_PCM_TUNE[WG_PCM_WAVE]

SYNTH

  • WG_WAVE_FORM - Timbre Temp Memory, Partial Parameter, WG WAVE FORM

SYNTH SQUARE

epitch_base += 0x9'10d

SYNTH SAW

epitch_base += 0x9'10d - 0x0'010

На что влияют

  • seg001_E580[].la32_pitch = pitch_base

Следует отметить, что частота задается в виде дробного десятичного числа с фиксированной запятой в формате 0xI'FFF, где I - целая часть, а FFF - дробная. Само значение является показателем степени 2 (экпонентой) частоты генератора в килогерцах. Например, базовой частотой для большинства PCM сэмплов является 0x5'000, что равняется 2^5.000 = 32.000КГц.

Для синтеза синусоиды (режим SYNTH SQUARE) расчет значения epitch_base выглядит так:

epitch_base = LOG2(FREQ * 2 * 1.024) * 4096

То есть, частота генератора в два раза выше частоты звука. Более того, в килогерце считается не 1000Гц, а 1024Гц, то есть 2^10Гц. Возможно, это связано с тем, что LA32 тактируется генератором с частотой 16384КГц (2^14КГц).

Таблица MAP_PITCH[12], если перевести ее значения в обычные дроби, содержит в себе значения от 0 до 1: (n / 12), где n = 0..12. 12 - это количество полутонов в октаве.

Таблица MAP_KEYFOLLOW[17] содержит дробные коэффиценты, позволяющие линейно растянуть или сжать частоты тонов по нотам. По какой-то причине (видимо, чтобы повысить точность вычислений) эти коэффициенты удвоены. Поэтому, после умножения чисел с фиксированной запятой, помимо обычной коррекции разряда (деление на 1000h в нашем случае), результат еще и делится на 2.

Значение параметров по умолчанию:

WG_PITCH_KEYFOLLOW = 1; MAP_KEYFOLLOW[WG_PITCH_KEYFOLLOW] = 0x2000

TVA

Что используется

На что влияют

TVF

Что используется

  • Timbre Temp Memory, Partial Parameter, TVF_CUTOFF_FREQ
  • Timbre Temp Memory, Partial Parameter, TVF_KEY_FOLLOW
  • Timbre Temp Memory, Partial Parameter, WG_PITCH_KEYFOLLOW
  • Timbre Temp Memory, Partial Parameter, TVF_BIAS_POINT_DIR
  • Timbre Temp Memory, Partial Parameter, TVF_BIAS_LEVEL
  • Timbre Temp Memory, Partial Parameter, TVF RESONANCE

В общем виде, расчет значения регистра TVF_FREQ выглядит так:

tvf_freq = TVF_CUTOFF_FREQ - 50.0
REG_TVF_FREQ = TO_INT(tvf_freq - 125.5)

Как это ни странно, частота фильтра не зависит от частоты ноты. По всей видимости, фильть здесь не совсем фильтр, а коэффициент похожести сигнала на синусоиду. Подробней нужно смотреть в исходниках MUNT или в выходе LA32.
Лимиты на tvf_freq устанавливаются такие:

  • tvf_freq min = -64.0
  • tvf_freq max = 224.0 - (epitch / 16) - зависит от высоты ноты

Дальше, в расчет вводятся TVF Key Follow и TVF Bias Point:

// TVF Key Follow
tvf_freq += MAP_TVF_KEYFOLLOW[TVF_KEY_FOLLOW] - MAP_TVF_KEYFOLLOW[WG_PITCH_KEYFOLLOW]

// TVF Bias Point
if (TVF_BIAS_POINT_DIR >= 64) {    // >A1..>C7
    // TVF_BIAS_POINT_DIR(64..127) to MIDI_NOTE_A1..MIDI_NOTE_C7
    tvf_bias_note = TVF_BIAS_POINT_DIR - 64 + MIDI_NOTE_A1
    if (midi_note >= tvf_bias_note) {
        tvf_freq += tvf_bias_note * MAP_TVF_BIAS_LEVEL[TVF_BIAS_LEVEL]
    }
} else {                           // <A1..<C7
    // TVF_BIAS_POINT_DIR(0..63) to MIDI_NOTE_A1..MIDI_NOTE_C7
    tvf_bias_note = TVF_BIAS_POINT_DIR + MIDI_NOTE_A1
    if (g_midi_note < tvf_bias_note) {
        tvf_freq -= tvf_bias_note * MAP_TVF_BIAS_LEVEL[TVF_BIAS_LEVEL]
    }
}
TVF_RES = tvf_resonance + ((INT(tvf_resonance) / 4) * 32)

На что влияют

  • REG_TVF_FREQ
  • TVF_RES
Edit - History - Print - Recent Changes - Search
Page last modified on December 20, 2021, at 01:28 pm