Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
シンセサイザー入門
Search
Fadis
May 09, 2015
Programming
600
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
シンセサイザー入門
mbedのDAコンバータを使って色んな方式のシンセサイザーの仕組みを解説します
Fadis
May 09, 2015
More Decks by Fadis
See All by Fadis
ソフトウェアラスタライザ
fadis
1
790
3Dシーンの圧縮
fadis
2
890
Kernel/VM探検隊@関西 12回目 イベント会場から懇親会会場までの道のりマップ
fadis
0
110
安いハードウェアでVulkan
fadis
2
1.3k
ゲームの物理 剛体編
fadis
2
680
ゲームの物理
fadis
6
2.4k
バイラテラルアップサンプリング
fadis
5
1.2k
Kernel/VM探検隊@関西 12回目 大阪駅から会場までの道のりマップ
fadis
0
440
C++でシェーダを書く
fadis
6
5.4k
Other Decks in Programming
See All in Programming
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
120
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
400
XHTMLが残したもの
yosuke_furukawa
PRO
1
410
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
120
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
180
[KotlinConf Extended South Korea 2026] KotlinConf 2026 발표자 후기
wisemuji
0
100
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
140
이 함수, 실패하면 어떻게 되나요? null부터 Rich Errors까지, Kotlin 에러 처리 15년
haeti2
0
140
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
370
高専キャリア LT 発表内容
crysta1221
6
5.5k
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
130
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
1.7k
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing for humans not robots
tammielis
254
26k
The Invisible Side of Design
smashingmag
301
52k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
720
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
WENDY [Excerpt]
tessaabrams
12
39k
Into the Great Unknown - MozCon
thekraken
41
2.7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
The Spectacular Lies of Maps
axbom
PRO
1
980
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Documentation Writing (for coders)
carmenintech
77
5.5k
Transcript
γϯηαΠβʔೖ
দྛঘཧ !GBEJT@ 5XJUUFS ࣗݾհ
দྛঘཧ IUUQTHJUIVCDPN'BEJT HJUIVC͡Ί·ͨ͠ ࠓճհ͢Δίʔυ ͜͜Ͱެ։த ࣗݾհ
ݹͷੲ ୈҰճΧʔωϧ7.୳ݕୂ!ؔ CFFQԻͰԿ͕ग़དྷΔ͔
ࠓճΦʔσΟΦωλ CFFQԻͳΜͯένष͍͜ͱݴΘͣ ΨνͰγϯηαΠβʔΛ࡞Δ
ԻͷपʹΑͬͯԻ֊͕มΘΔ ͜͜ ͜͜
ؚ·Ε͍ͯΔपʹΑͬͯԻ৭͕มΘΔ ͜͜ͱ͔
γϯηαΠβʔͷجຊ ҙਤͨ͠Ի֊ʹରԠ͢ΔपΛ ओͱ͢ΔΛ࡞Δ
ྲྀߦͷϚΠίϯNCFE͞Μ AnalogOut
#include "mbed.h" AnalogOut audio_out(p18); const float freq_table[ 8 ] =
{ 523.25113f, 587.32953f, 659.25511f, 698.45646f, 783.99087f, 880.00000f, 987.76660f, 1046.5022f, }; int main() { while(1) { for( int note = 0; note != 8; ++note ) for( float time = 0.0f; time < 1.0f; time += 1.0f/16000.0f ) { Timer used_time; used_time.start(); audio_out = sinf( time * freq_table[ note ] * 3.141592f * 2.0f ) * 0.5f + 0.5f; used_time.stop(); wait(1.0f/16000.0f-used_time.read()); } } }
αΠζͷ߹ͰಈըΧοτʜ
ͬͱෳࡶͳԻΛग़͍ͨ͠ ϑΝϛίϯۣܗͱࡾ֯ͷ छྨͷܗ͔͑͠ͳ͍ͷʹ ଟ࠼ͳԻ৭ΛͰΔ͜ͱ͕ग़དྷΔͷԿނ͔ ۣܗ ࡾ֯
Τϯϕϩʔϓ ͬͱෳࡶͳԻΛग़͍ͨ͠ ԻྔΛܦա࣌ؒʹԠͯ͡มԽͤ͞Δ ͜͜Ͱ໐Β͢ͷΛΊͨ ͜͜Ͱ໐Β͠͡Ίͨ
ΞλοΫ ϐΞϊ όΠΦϦϯ ໐Γ͡Ίͷ Իྔ͕࠷େ͖͍ ໐Γ͡Ί͔ͯΒ ঃʑʹԻྔ͕େ͖͘ͳΔ ͜ͷ෦ͷ͞Λม͑Δ͜ͱͰରԠ
σΟέΠ γϩϑΥϯ Ϊλʔ ໐Β͠͡Ίͯ࠷େԻྔʹୡͨ͠ޙ ͙͢ʹԻྔ͕Լ͕Δ ໐Β͠͡Ίͯ࠷େԻྔʹୡͨ͠ޙ Ώͬ͘ΓԻྔ͕Լ͕Δ ͜ͷ෦ͷ͞Λม͑Δ͜ͱͰରԠ
αεςΠϯ ϐΞϊ ΦϧΨϯ ݤ൫Λԡ͍ͯ͠Δ࣌ؒʹؔΘΒͣ ͋Δఔͷ࣌ؒͰԻ͕ফ͑Δ ݤ൫Λԡ͍ͯ͠ΔݶΓࡍݶͳ͘ Ի͕໐Γଓ͚Δ ͜ͷ෦ͷେ͖͞Λม͑Δ͜ͱͰରԠ
ϦϦʔε ΦϧΨϯ ενʔϧυϥϜ ͘ͷΛΊΔͱ ൺֱత࣌ؒͰԻ͕ফ͑Δ ͜ͷ෦ͷ͖Λม͑Δ͜ͱͰରԠ ͘ͷΛΊͯԻ͕ ফ͑Δ·Ͱʹ͋Δఔͷ࣌ؒΛཁ͢
Τϯϕϩʔϓ º
#include "mbed.h" AnalogOut audio_out(p18); DigitalIn button(p19); class Envelope { bool
note_stat; float prev; public: Envelope() : note_stat( true ), prev( 0.0f ) {} void off() { note_stat = false; } float operator()( float _time ) { if( note_stat ) { if( _time < 0.2f ) prev = _time / 0.2f; else if( _time < 0.7f ) prev = 1.0f - ( _time - 0.2f ); else prev = 0.5f; return prev; } else return ( prev - _time < 0.0f ) ? 0.0f : prev - _time; } }; int main() { while(1) { Envelope envelope; float time, note_off_time; for( time = 0.0f; button; time += 1.0f/16000.0f ) { Timer used_time; used_time.start(); audio_out = envelope( time ) * sinf( time * 880.0f * 3.141592f * 2.0f ) * 0.4f + 0.5f; used_time.stop(); wait(1.0f/16000.0f-used_time.read()); } envelope.off(); for( note_off_time = time; !button; time += 1.0f/16000.0f ) { Timer used_time; used_time.start(); audio_out = envelope( time - note_off_time ) * sinf( time * 880.0f * 3.141592f * 2.0f ) * 0.4f + 0.5f; used_time.stop(); wait(1.0f/16000.0f-used_time.read()); } } }
αΠζͷ߹ͰಈըΧοτʜ
ϋϞϯυΦϧΨϯ αΠϯͱ͔ۣܗͱ͔Ͱͳ͘ ͬͱෳࡶͳܗΛ͏͜ͱͰ ଟ࠼ͳԻ৭ΛͰ͍ͨ ෳͷαΠϯΛॏͶ߹ΘͤΔ ࡞ઓ
ϋϞϯυΦϧΨϯ ഒ ഒ ഒ ഒ ̏ഒ ̐ഒ ഒ ̒ഒ ഒ
جԻ ͜ΕΒͷഒԻΛҙͷԻྔͰॏͶ߹ΘͤΔ
ϋϞϯυΦϧΨϯ ຊͷϋϞϯυΦϧΨϯ αΠϯͷࠁ·Εͨຕͷԁ൫Λ ߴճసͤ͞Δ͜ͱͰ֤पͷΛ࡞͍ͬͯͨ ϚΠίϯͰ؆୯ʹαΠϯΛ࡞ΕΔ࣌Ͱ ຊʹྑ͔ͬͨ
... template< typename Traits > class Hammond { public: Hammond(){}
fixed32< 16 > operator()( fixed32< 16 > _time ) { static const fixed32< 16 > scale_16 = 220.0f; static const fixed32< 16 > scale_8 = 440.0f; static const fixed32< 16 > scale_513 = 659.3f; static const fixed32< 16 > scale_4 = 880.0f; static const fixed32< 16 > scale_223 = 1318.5f; static const fixed32< 16 > scale_2 = 1760.0f; static const fixed32< 16 > scale_135 = 2217.0f; static const fixed32< 16 > scale_113 = 2637.0f; static const fixed32< 16 > scale_1 = 3520.0f; fixed32< 16 > sum = 0.0f; sum += sint( _time * scale_16 ) * Traits::level_16; sum += sint( _time * scale_8 ) * Traits::level_8; sum += sint( _time * scale_513 ) * Traits::level_513; sum += sint( _time * scale_4 ) * Traits::level_4; sum += sint( _time * scale_223 ) * Traits::level_223; sum += sint( _time * scale_2 ) * Traits::level_2; sum += sint( _time * scale_135 ) * Traits::level_135; sum += sint( _time * scale_113 ) * Traits::level_113; sum += sint( _time * scale_1) * Traits::level_1; fixed32< 16 > max = 0.0f; max += Traits::level_16; max += Traits::level_8; max += Traits::level_513; max += Traits::level_4; max += Traits::level_223; max += Traits::level_2; max += Traits::level_135; max += Traits::level_113; max += Traits::level_1; sum /= max; return sum; } private: }; ...
αΠζͷ߹ͰಈըΧοτʜ
ϋϞϯυΦϧΨϯ ϑʔϦΤڃΑΓ ͋ΒΏΔܗαΠϯͷॏͶ߹ΘͤͰ࡞ΕΔ͕ Ұൠʹेͳ࣭ΛಘΔҝʹཁٻ͞ΕΔ αΠϯͷඇৗʹଟ͘ ͔͔ͨͩݸఔͷαΠϯͰ େͨ͠Ի৭ͷࣗ༝ಘΒΕͳ͍
'.Իݯ αΠϯͱ͔ۣܗͱ͔Ͱͳ͘ ͬͱෳࡶͳܗΛ͏͜ͱͰ ଟ࠼ͳԻ৭ΛͰ͍ͨ '.มௐΛͬͯαΠϯΛΊΔ ࡞ઓ
ΦϖϨʔλ PVUQVUTJO DMPDL JOQVU FOWFMPQF ·ͨผͷΦϖϨʔλ ΦʔσΟΦग़ྗ·ͨผͷΦϖϨʔλ
ΦϖϨʔλྻͷ'.Իݯ ΦϖϨʔλ ΦϖϨʔλ ΦʔσΟΦग़ྗ
ΦϖϨʔλฒྻͷ'.Իݯ ΦϖϨʔλ ΦϖϨʔλ ΦʔσΟΦग़ྗ
ೖྗଆͷԻྔͰΈ۩߹͕ௐઅͰ͖Δ ΦϖϨʔλ ΦϖϨʔλ ΦϖϨʔλ ΦϖϨʔλ
ೖྗଆͷԻྔͰΈ۩߹͕ௐઅͰ͖Δ PVUQVUTJO DMPDL JOQVU FOWFMPQF ΦϖϨʔλʹ Τϯϕϩʔϓ͕͍͍ͭͯΔ ΦʔσΟΦग़ྗʹܨ͕͍ͬͯͳ͍ ΦϖϨʔλͷΤϯϕϩʔϓ
ܗͷΈΛ࣌ؒมԽͤ͞ΔͨΊʹ͑Δ
... class Const { public: fixed32< 16 > operator()( fixed32<
16 > _time ) { static const fixed32< 16 > value = 0; return value; } }; ! template< typename Source > class FM { public: FM() {} void off( fixed32< 16 > _off_time ) { envelope.off( _off_time ); } fixed32< 16 > operator()( fixed32< 16 > _time ) { fixed32< 16 > looped_time = _time - static_cast< int >( _time ); return sint( ( looped_time * 880.0f + source( _time ) / 2 ) ) * envelope( _time ); } private: Source source; Envelope envelope; }; ! int main() { while(1) { FM< FM< Const > > fm; fixed32< 16 > time, note_off_time; for( time = 0.0f; button; time += 1.0f/16000.0f ) { Timer used_time; used_time.start(); audio_out = fm( time ) * 0.4f + 0.5f; used_time.stop(); wait(1.0f/16000.0f-used_time.read()); } fm.off( time ); ...
αΠζͷ߹ͰಈըΧοτʜ
'.Իݯ '.มௐͷ݁Ռײతʹ༧͠ਏ͍ͨΊ ҙਤͨ͠Ի৭Λ࡞ΔͨΊʹࢼߦࡨޡ͕ඞཁ
ܗςʔϒϧԻݯ αΠϯͱ͔ۣܗͱ͔Ͱͳ͘ ͬͱෳࡶͳܗΛ͏͜ͱͰ ଟ࠼ͳԻ৭ΛͰ͍ͨ ࣄલʹ༻ҙͨ͠ܗσʔλΛ͏ ࡞ઓ
ܗςʔϒϧԻݯ ٕज़తʹ໘ന͘ͳ͍͚Ͳ ͦΕͳΓʹྑ͍Ի͕ग़Δํ๏ ͋Β͔͡Ίຊͷָث͔ΒԻ͖ͯͨ͠ ܗσʔλΛԻ֊ʹରԠ͢Δ͞ͰᢞΊΔ ྻ
... class Guiter { public: virtual fixed32< 16 > operator()(
fixed32< 16 > _pos ) { static const int16_t guiter_table[ 512 ] = { -32735, -32583, -32431, -32279, -32127, -31975, -31823, -31671, ... -27519, -28171, -28823, -29475, -30127, -30779, -31431, -32083, }; fixed32< 16 > result; fixed32< 16 > a4 = _pos * 220.0f; int pos = ( a4.get() >> 7 ) % 512; // pos = pos * 880 % 512; int32_t value = static_cast< int32_t >( guiter_table[ pos ] ) << 1; result.set( value ); return result * envelope( _pos ); } void off( fixed32< 16 > _off_time ) { envelope.off( _off_time ); } private: Envelope envelope; }; ...
αΠζͷ߹ͰಈըΧοτʜ
ܗςʔϒϧԻݯ ࣮ͷଘࡏ͠ͳ͍ԻΛ࡞Δͷࠔ ࣌ؒมԽ͢ΔԻ৭Λѻ͏ͷ͕ࠔ
࠷ऴతʹग़དྷ্͕ͬͨͷ ͦͷଞ৭ʑ࣮͚ͨ͠Ͳ ͦͷΜͷղઆ·ͨͷػձʹ Ψοπͷ͋Δਓ ιʔεΛݟͯΈΔͱ͍͍͔
IUUQZPVUVCFSY5RX&:#.
ษڧձ෮शࢿྉ IUUQCJUMZF2,WE& ιʔείʔυ IUUQCJUMZRJBR'
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠