summaryrefslogtreecommitdiff
path: root/public/posts/drum-sequencer/index.html
blob: 385c1cdbfbc76b0986d221bdd9c693225e4dbaaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
<!doctype html><html lang=en><head><meta charset=utf-8><meta content="width=device-width,initial-scale=1.0" name=viewport><title>Making a Drum Sequencer - Venkata Rao Dechiraju</title><meta content="I always looked at Teenage Engineering and thought it was pretty cool and given I have a sem break right now, I thought I can make one too. shouldn’t be hard ri…" name=description><link href=https://veradec.xyz/posts/drum-sequencer/ rel=canonical><link href=https://veradec.xyz/favicon/favicon.ico rel=icon type=image/x-icon><link href=https://veradec.xyz/favicon/favicon-16x16.png rel=icon sizes=16x16 type=image/png><link href=https://veradec.xyz/favicon/favicon-32x32.png rel=icon sizes=32x32 type=image/png><link href=https://veradec.xyz/favicon/apple-touch-icon.png rel=apple-touch-icon sizes=180x180><link href=https://veradec.xyz/favicon/site.webmanifest rel=manifest><link as=style href=https://veradec.xyz/style.css rel=preload><link href=https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css rel=stylesheet><script defer src=https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js></script><script onload="renderMathInElement(document.body, {
        delimiters: [
          {left: '$$', right: '$$', display: true},
          {left: '$', right: '$', display: false}
        ]
      });" defer src=https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js></script><meta content="blog, tech, programming" name=keywords><meta content="Venkata Rao Dechiraju" name=author><meta content="index, follow" name=robots><meta content=#1e3a8a name=theme-color><meta content=article property=og:type><meta content=https://veradec.xyz/posts/drum-sequencer/ property=og:url><meta content="Making a Drum Sequencer" property=og:title><meta content="I always looked at Teenage Engineering and thought it was pretty cool and given I have a sem break right now, I thought I can make one too. shouldn’t be hard ri…" property=og:description><meta content="Venkata Rao Dechiraju" property=og:site_name><meta content=https://veradec.xyz/static/banner.png property=og:image><meta content=summary_large_image name=twitter:card><meta content="Making a Drum Sequencer" name=twitter:title><meta content="I always looked at Teenage Engineering and thought it was pretty cool and given I have a sem break right now, I thought I can make one too. shouldn’t be hard ri…" name=twitter:description><meta content=https://veradec.xyz/static/banner.png name=twitter:image><script type=application/ld+json>
    {
      "@context": "https://schema.org",
      "@type": "WebSite",
      "name": "Venkata Rao Dechiraju",
      "url": "https:&#x2F;&#x2F;veradec.xyz&#x2F;",
      "description": "made by a actual human"
      
      ,"author": {
        "@type": "Person",
        "name": "Venkata Rao Dechiraju"
        
        ,"url": "https:&#x2F;&#x2F;verade.xyz"
        
      }
      
    }
    </script><link title="atom feed for Venkata Rao Dechiraju" href=https://veradec.xyz/atom.xml rel=alternate type=application/atom+xml><link title="rss feed for Venkata Rao Dechiraju" href=https://veradec.xyz/rss.xml rel=alternate type=application/rss+xml><link href=https://veradec.xyz/style.css rel=stylesheet><script type=application/ld+json>
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Making a Drum Sequencer",
  "url": "https:&#x2F;&#x2F;veradec.xyz&#x2F;posts&#x2F;drum-sequencer&#x2F;"
  
  ,"datePublished": "2026-05-27T00:00:00Z"
  
  
  
  ,"author": {
    "@type": "Person",
    "name": "Venkata Rao Dechiraju"
    
    ,"url": "https:&#x2F;&#x2F;verade.xyz"
    
  }
  
}
</script><body><div class=background-container><img alt class=background-image src=Raja_Ravi_Varma,_Sakunthala_Pathralekhan.jpg></div><div aria-label="Reading progress" class=reading-progress id=reading-progress role=progressbar></div><a class=skip-to-content href=#content>skip to content</a><div class=wrap><header><a href=https://veradec.xyz/ id=home-link> <span aria-hidden=true id=back-icon> <svg viewbox="0 0 24 24" fill=none stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2><polyline points="15 18 9 12 15 6"></polyline></svg> </span> <span id=back-text>back</span> </a></header><div id=content><div class=hero><h1>Making a Drum Sequencer</h1><div class=hero-meta><span> Wed May 27, 2026 </span><span>·</span><span>2 min read</span><span>·</span><span>375 words</span></div></div><nav aria-label="Table of contents" class=table-of-contents><div class=toc-header><span class=toc-title>Contents</span></div><ul class=toc-list><li class=toc-item><a class=toc-link data-target=the-design href=#the-design>The Design</a><li class=toc-item><a class=toc-link data-target=the-prototyping href=#the-prototyping>The Prototyping</a></ul></nav><script>'use strict';
    
    (function() {
        const toc = document.querySelector('.table-of-contents');
        if (!toc) return;
        
        function initTableOfContents() {
            const links = document.querySelectorAll('.toc-link');
            
            if (!links.length) return;

            requestAnimationFrame(() => {
                toc.classList.add('visible');
            });

            const headingMap = new Map();
            let observerInstance = null;
            
            links.forEach(link => {
                const targetId = link.dataset.target;
                const heading = document.getElementById(targetId);
                if (heading) {
                    headingMap.set(targetId, { link, heading });
                }
            });

            const observerOptions = {
                rootMargin: '-40% 0px -50% 0px',
                threshold: 0
            };

            observerInstance = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        links.forEach(link => link.classList.remove('toc-link--active'));
                        
                        const targetId = entry.target.id;
                        const item = headingMap.get(targetId);
                        if (item) {
                            item.link.classList.add('toc-link--active');
                        }
                    }
                });
            }, observerOptions);

            headingMap.forEach(({ heading }) => {
                observerInstance.observe(heading);
            });

            const cleanup = () => {
                if (observerInstance) {
                    observerInstance.disconnect();
                    observerInstance = null;
                }
            };

            window.addEventListener('beforeunload', cleanup);
            window.addEventListener('pagehide', cleanup);
        }
        
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initTableOfContents);
        } else {
            initTableOfContents();
        }
    })();</script><article><p>I always looked at Teenage Engineering and thought it was pretty cool and given I have a sem break right now, I thought I can make one too. shouldn’t be hard right?<br> and after i started composing music, Techno was a genre I always wanted to try but i couldn’t, and then an idea popped up, maybe I can create a suite of instruments<blockquote><p>a Synth</blockquote><blockquote><p>a Drum Sequencer</blockquote><blockquote><p>a Vocoder</blockquote><p>and start making techno on them? Sounds nice innit?<br> <br><h1 id=the-design>The Design</h1><p>I wanted the design to look a little retro 80’s esque, and I wanted it to be little simpler (because I will have suite of appliances to generate different sounds, so would rather have one that is simple and does it job well) and I drew a few sketches and ended with something that looks very nice<div style=justify-content:center;display:flex><img alt="Drum Sequencer Rough Sketch" src=/dq_sketch.png style=width:50%;transform:rotate(-90deg)></div><h1 id=the-prototyping>The Prototyping</h1><p>with the <em>beautifully</em> crafted picture in hand, now the plan is to prototype<p>I needed around 16 Buttons – which I am going to pull of some keyboards i archived (They paid off innit?).<p>I might need to get some more potentiometers and find a way to make a matrix the LEDs and Buttons, Once That is done, Getting the whole thing shouldn’t be that tough (atleast I hope it isn’t)</article></div><div class=bottom-menu><p><a href=/posts>posts</a> <a href=/about>about</a> <a href=https://github.com/veradec>github</a> <a href=/authors>authors</a> <a href=/tags>tags</a> <a href=/categories>categories</a></div><button aria-label="Scroll to top" id=scroll-to-top><svg viewbox="0 0 24 24" aria-hidden=true fill=none stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2><polyline points="18 15 12 9 6 15"></polyline></svg></button><footer><div class=sam-footer>Built using Zola & Prism theme</div></footer></div><script>'use strict';

(function() {
    const SVG_ICONS = {
        copy: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',
        check: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>',
        error: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>'
    };

    function debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func(...args), wait);
        };
    }

    function initNavigation() {
        try {
            const homeLink = document.getElementById('home-link');
            const backIcon = document.getElementById('back-icon');
            const backText = document.getElementById('back-text');
            
            if (!homeLink) return;
            
            const homeText = 'back';
            const isHomePage = window.location.pathname === '/' || window.location.pathname === '/index.html';
            
            if (backIcon && isHomePage) {
                backIcon.style.display = 'none';
            }
            
            if (backText) {
                backText.textContent = homeText;
            }
            
            homeLink.setAttribute('aria-label', `Go to ${homeText.toLowerCase()} page`);
        } catch (error) {
            console.error('Navigation init failed:', error);
        }
    }

    function initScrollToTop() {
        try {
            const scrollToTopBtn = document.getElementById('scroll-to-top');
            if (!scrollToTopBtn) return;
            
            const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
            
            const toggleVisibility = debounce(() => {
                if (window.scrollY > 300) {
                    scrollToTopBtn.classList.add('visible');
                } else {
                    scrollToTopBtn.classList.remove('visible');
                }
            }, 100);
            
            window.addEventListener('scroll', toggleVisibility, { passive: true });
            toggleVisibility();
            
            scrollToTopBtn.addEventListener('click', () => {
                window.scrollTo({
                    top: 0,
                    behavior: prefersReducedMotion ? 'auto' : 'smooth'
                });
            });
        } catch (error) {
            console.error('Scroll to top init failed:', error);
        }
    }

    
    function initCopyCodeButtons() {
        try {
            const codeBlocks = document.querySelectorAll('pre code');
            
            codeBlocks.forEach((codeBlock) => {
                const pre = codeBlock.parentElement;
                
                const wrapper = document.createElement('div');
                wrapper.className = 'code-block-wrapper';
                pre.parentNode.insertBefore(wrapper, pre);
                wrapper.appendChild(pre);
                
                const copyButton = document.createElement('button');
                copyButton.className = 'copy-code-button';
                copyButton.innerHTML = SVG_ICONS.copy;
                copyButton.setAttribute('aria-label', 'Copy code to clipboard');
                copyButton.setAttribute('title', 'Copy code');
                
                wrapper.appendChild(copyButton);
                
                copyButton.addEventListener('click', async () => {
                    const code = codeBlock.textContent;
                    
                    try {
                        if (navigator.clipboard && window.isSecureContext) {
                            await navigator.clipboard.writeText(code);
                        } else {
                            const textArea = document.createElement('textarea');
                            textArea.value = code;
                            textArea.style.position = 'fixed';
                            textArea.style.left = '-999999px';
                            document.body.appendChild(textArea);
                            textArea.select();
                            document.execCommand('copy');
                            document.body.removeChild(textArea);
                        }
                        
                        copyButton.innerHTML = SVG_ICONS.check;
                        copyButton.classList.add('copied');
                        copyButton.setAttribute('aria-label', 'Code copied');
                        
                        setTimeout(() => {
                            copyButton.innerHTML = SVG_ICONS.copy;
                            copyButton.classList.remove('copied');
                            copyButton.setAttribute('aria-label', 'Copy code to clipboard');
                        }, 2000);
                    } catch (err) {
                        console.error('Failed to copy code:', err);
                        
                        copyButton.innerHTML = SVG_ICONS.error;
                        copyButton.classList.add('error');
                        copyButton.setAttribute('aria-label', 'Copy failed');
                        
                        setTimeout(() => {
                            copyButton.innerHTML = SVG_ICONS.copy;
                            copyButton.classList.remove('error');
                            copyButton.setAttribute('aria-label', 'Copy code to clipboard');
                        }, 2000);
                    }
                });
            });
        } catch (error) {
            console.error('Copy code buttons init failed:', error);
        }
    }
    

    
    function initSmoothScroll() {
        try {
            const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
            if (prefersReducedMotion) return;
            
            document.querySelectorAll('a[href^="#"]').forEach(anchor => {
                anchor.addEventListener('click', function (e) {
                    const href = this.getAttribute('href');
                    if (href === '#' || href.length <= 1) return;
                    
                    e.preventDefault();
                    const target = document.querySelector(href);
                    
                    if (target) {
                        const offset = 80;
                        const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - offset;
                        
                        window.scrollTo({
                            top: targetPosition,
                            behavior: 'smooth'
                        });
                        
                        if (window.history.pushState) {
                            window.history.pushState(null, null, href);
                        }
                        
                        if (!target.hasAttribute('tabindex')) {
                            target.setAttribute('tabindex', '-1');
                        }
                        target.focus({ preventScroll: true });
                    }
                });
            });
        } catch (error) {
            console.error('Smooth scroll init failed:', error);
        }
    }
    

    
    function initReadingProgress() {
        try {
            const progressBar = document.getElementById('reading-progress');
            if (!progressBar) return;
            
            const updateProgressBar = debounce(() => {
                const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                const scrolled = height > 0 ? (winScroll / height) * 100 : 0;
                progressBar.style.width = scrolled + '%';
            }, 16);
            
            window.addEventListener('scroll', updateProgressBar, { passive: true });
            updateProgressBar();
        } catch (error) {
            console.error('Reading progress init failed:', error);
        }
    }
    

    function initPageLoadingState() {
        try {
            document.addEventListener('click', (e) => {
                const link = e.target.closest('a[href^="/"], a[href^="https:&#x2F;&#x2F;veradec.xyz&#x2F;"]');
                if (link && !link.target && !link.getAttribute('download')) {
                    document.body.classList.add('page-loading');
                }
            });
            
            window.addEventListener('pageshow', () => {
                document.body.classList.remove('page-loading');
            });
        } catch (error) {
            console.error('Page loading state init failed:', error);
        }
    }

    function init() {
        initNavigation();
        initScrollToTop();
        initPageLoadingState();
        
        
        initCopyCodeButtons();
        
        
        
        initSmoothScroll();
        
        
        
        initReadingProgress();
        
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();</script>