片山博文MZの掲示板 33330


この掲示板について

1:片山博文MZ:

2011/03/24 (Thu) 15:30:40

片山博文MZが配布するソフト・プログラムなどに関する掲示板です。関係のない話題などは削除されます。また、禁止ワードが設定されています。適切にご利用ください。

ホームページはこちらです:
http://katahiromz.web.fc2.com/
55:書けるかな? :

2015/12/16 (Wed) 21:13:41

LFOの音量変化はオペレータ毎にパラメータがあるんだね。前に書き込んだのでは対応できない。
自分には正解がわからんので何とも言えないけど、適当に作ってみた。変数名なんかも適当。真面目にデバッグしてない。
特に、LFOの振幅を決める式の仕様とか全然わからんから // TBD ってコメント付けた。
本気で88そっくりな音にするんなら、実機とエミュレータを駆使してデータを取るべきなのかな。私はやれないけど。

YM2203.h
92,93c92,93
< void set_pitch(int ch, int octave, int key);
< void set_volume(int ch, int volume);
---
> void set_pitch(int ch, int octave, int key, int adj = 0);
> void set_volume(int ch, int volume, int adj1 = 0, int adj2 = 0, int adj3 = 0, int adj4 = 0);

YM2203.cpp
93c93
< void YM2203::set_pitch(int ch, int octave, int key) {
---
> void YM2203::set_pitch(int ch, int octave, int key, int adj) {
99c99
< ((FM_PITCH_TABLE[key] >> 8) & 0x07)
---
> (((FM_PITCH_TABLE[key]+adj) >> 8) & 0x07)
103c103
< data = (uint8_t)FM_PITCH_TABLE[key];
---
> data = (uint8_t)(FM_PITCH_TABLE[key]+adj);
122c122
< void YM2203::set_volume(int ch, int volume) {
---
> void YM2203::set_volume(int ch, int volume, int adj1, int adj2, int adj3, int adj4) {
140c140
< data = ((m_fm_timbres[ch]->tl[OPERATOR_4] + attenate) & 0x7F);
---
> data = ((m_fm_timbres[ch]->tl[OPERATOR_4] + attenate - adj4) & 0x7F);
145c145
< data = ((m_fm_timbres[ch]->tl[OPERATOR_2] + attenate) & 0x7F);
---
> data = ((m_fm_timbres[ch]->tl[OPERATOR_2] + attenate - adj2) & 0x7F);
151c151
< data = ((m_fm_timbres[ch]->tl[OPERATOR_3] + attenate) & 0x7F);
---
> data = ((m_fm_timbres[ch]->tl[OPERATOR_3] + attenate - adj3) & 0x7F);
157c157
< data = ((m_fm_timbres[ch]->tl[OPERATOR_1] + attenate) & 0x7F);
---
> data = ((m_fm_timbres[ch]->tl[OPERATOR_1] + attenate - adj1) & 0x7F);


YM2203_Timbre.h
61a62
> uint8_t ams[OPERATOR_NUM]; // Amplitude Modulation Sensitivity (AMS)
[okamoto@koub

YM2203_Timbre.cpp
cpp YM2203_Timbre.cpp
27d26
< // [1-4][9] : ビブラート関係の設定は未対応
36a36,40
> // [1-4][9] : ビブラート関係の設定
> ams[OPERATOR_1] = (uint8_t)array[1][9];
> ams[OPERATOR_2] = (uint8_t)array[2][9];
> ams[OPERATOR_3] = (uint8_t)array[3][9];
> ams[OPERATOR_4] = (uint8_t)array[4][9];

soundplayer.cpp
9c9
< #define CLOCK 4000000
---
> #define CLOCK 8000000
13a14,133
> #define LFO_INTERVAL 150
>
> class LFOctrl {
> int m_waveform;
> int m_qperiod; // quarter of period
> int m_count;
> int m_phase; // 0, 1, 2 or 3
> float m_adj_p_max;
> float m_adj_v_max[4];
> float m_adj_p_diff;
> float m_adj_v_diff[4];
> public:
> float m_adj_p; // for pitch
> float m_adj_v[4]; // for volume
>
> public:
> LFOctrl() {
> }
>
> void init_for_timbre(YM2203_Timbre *p_timbre) {
> int i;
> m_waveform = p_timbre->waveForm;
> m_qperiod = (p_timbre->speed)?900*LFO_INTERVAL/(4*p_timbre->speed):0;
> //m_count = 0;
> m_phase = 0;
> m_adj_p_max = p_timbre->pmd * (float)p_timbre->pms / 2.0; // TBD
> for(i=0; i<4; i++) m_adj_v_max[i] = p_timbre->amd * (float)p_timbre->ams[i] / 2; // TBD
> init_for_phase(true);
> }
>
> void init_for_keyon(YM2203_Timbre *p_timbre) {
> if (p_timbre->sync) {
> m_phase = 0;
> init_for_phase();
> }
> }
>
> void increment() {
> int i;
> if (0 == m_qperiod) return;
> m_count++;
> if (m_count < m_qperiod) {
> m_adj_p += m_adj_p_diff;
> for(i=0; i<4; i++) m_adj_v[i] += m_adj_v_diff[i];
> }
> else {
> m_phase = (m_phase + 1) & 3;
> init_for_phase();
> }
> }
>
> private:
> void init_for_phase(bool flag_first = false) {
> int i;
> m_count = 0;
> if (flag_first) {
> switch (m_waveform) {
> case 0: // saw
> m_adj_p = 0;
> for(i=0; i<4; i++) m_adj_v[i] = 0;
> m_adj_p_diff = m_adj_p_max / (m_qperiod * 2);
> for(i=0; i<4; i++) m_adj_v_diff[i] = m_adj_v_max[i] / (m_qperiod * 2);
> break;
> case 1: // square
> m_adj_p = -m_adj_p_max;
> for(i=0; i<4; i++) m_adj_v[i] = -m_adj_v_max[i];
> m_adj_p_diff = 0;
> for(i=0; i<4; i++) m_adj_v_diff[i] = 0;
> break;
> case 2: // triangle
> m_adj_p = 0;
> for(i=0; i<4; i++) m_adj_v[i] = 0;
> m_adj_p_diff = m_adj_p_max / m_qperiod;
> for(i=0; i<4; i++) m_adj_v_diff[i] = m_adj_v_max[i] / m_qperiod;
> break;
> default: // sample and hold
> //m_adj_p = m_adj_p_max * (rand() * 2.0 / RAND_MAX - 1);
> //for(i=0; i<4; i++) m_adj_v[i] = m_adj_v_max[i] * (rand() * 2.0 / RAND_MAX - 1);
> m_adj_p_diff = 0;
> for(i=0; i<4; i++) m_adj_v_diff[i] = 0;
> break;
> }
> }
> switch (m_waveform) {
> case 0: // saw
> if (0 == m_phase) {
> m_adj_p = 0;
> for(i=0; i<4; i++) m_adj_v[i] = 0;
> }
> else if (2 == m_phase) {
> m_adj_p = -m_adj_p;
> for(i=0; i<4; i++) m_adj_v[i] = -m_adj_v[i];
> }
> break;
> case 1: // square
> if (0 == (m_phase & 1)) {
> m_adj_p = -m_adj_p;
> for(i=0; i<4; i++) m_adj_v[i] = -m_adj_v[i];
> }
> break;
> case 2: // triangle
> if (0 == m_phase) {
> m_adj_p = 0;
> for(i=0; i<4; i++) m_adj_v[i] = 0;
> }
> else if (1 == (m_phase & 1)) {
> m_adj_p_diff = -m_adj_p_diff;
> for(i=0; i<4; i++) m_adj_v_diff[i] = -m_adj_v_diff[i];
> }
> break;
> default: // sample and hold
> if (0 == (m_phase & 1)) {
> m_adj_p = m_adj_p_max * (rand() * 2.0 / RAND_MAX - 1);
> for(i=0; i<4; i++) m_adj_v[i] = m_adj_v_max[i] * (rand() * 2.0 / RAND_MAX - 1);
> }
> break;
> }
> }
> }; // LFOctrl
>
100a221,222
> LFOctrl lc;
>
116a239
> lc.init_for_timbre(&timbre);
121a245
> lc.init_for_keyon(&(m_setting.m_timbre));
127c251,265
< ym.mix(&data[isample * 2], nsamples);
---
> {
> int unit;
> while(nsamples) {
> unit = SAMPLERATE/LFO_INTERVAL;
> if (unit > nsamples) unit = nsamples;
> ym.mix(&data[isample * 2], unit);
> isample += unit;
> if (note.m_key != -1) {
> lc.increment();
> ym.set_volume(ch, 15, lc.m_adj_v[0], lc.m_adj_v[1], lc.m_adj_v[2], lc.m_adj_v[3]);
> ym.set_pitch(ch, note.m_octave, note.m_key, lc.m_adj_p);
> }
> nsamples -= unit;
> }
> }
129d266
< isample += nsamples;
306c443
< int main(void) {
---
> int main(int ac, char *av[]) {
311c448
< phrase->m_setting.m_octave = 4;
---
> phrase->m_setting.m_octave = 3;
315c452
< phrase->m_setting.m_tone = 15; // @15 DESCENT
---
> phrase->m_setting.m_tone = (ac<2)?15:atoi(av[1]); // @15 DESCENT

  • 名前: E-mail(省略可):
  • 画像:

Copyright © 1999- FC2, inc All Rights Reserved.