전기기타 디지털 꾹꾹이 자작 (D.I.Y. Electric Guitar Digital Stompbox)

  쓰고 있지 않던 DSP (Digital Signal Processor) 평가 보드를 활용하여 전기기타용 꾹꾹이를 자작해 봤다. 기타 전문가도 아니고 입문용 싼 기타로 잠깐씩 취미삼아 연주하는 정도인지라 디스토션하고 딜레이 한 개 정도면 충분하다. 그래서 만들어 봤다. 디스토션과 딜레이 두 가지 이펙터만 구현하여 DSP보드에 집어 넣었다. 우선, 적용한 하드웨어는 DSP 평가보드로, Spectrum Digital TMS320C6416T DSK Starter Kit[1]인데 [Fig. 1]처럼 생겼다. 이게 나온지 10년 가까이 되고 고정 소수점 연산 이긴 하지만 1GHz 동작속도에 실수 연산용 하드웨어가 내장되어 있어 성능은 차고 넘친다. 오디오 신호처리를 위한 코덱칩과 AFE (Analog Front End) 회로가 잘 구성되어 있다. 여기에 LCD 디스플레이와 풋 스위치 (Foot Switch)를 추가로 장착 하였다.
  I got a cheap electric guitar for hobby and as you already know, effector or stompbox is essential for the electric guitar to play Hard Rock or Heavy Metals. Since I'm not a guitar expert, just distortion and delay are enough for me and I made one (distortion and delay integrated) by myself. I hope to share my D.I.Y. digital stompbox result in this text. For digital signal processing, I used old but still good DSP evaluation board - Spectrum Digital TMS320C6416T DSK Starter Kit[1], [Fig. 1].
[Fig. 1] DSP Evaluation Kit

  우선 디지털 오디오 이펙터와 신호처리에 대한 지식이 필요한데 관련 자료들을 뒤져보니 거의 교과서 처럼 등장하는 'DAFX: Digital Audio Effects'[2]라는 책이 있어 오버드라이브와 디스토션 관련 내용만 일단 찾아 봤다. 디스토션 전달 함수가 비교적 간단하여 이것만 적용하면 될 줄 알았는데, 교과서는 그냥 교과서 일뿐 실제 구현하면서 겪어 보니 무엇인가 더 많은 것들이 필요하였다. 고난의 시작이였다. 책에 소개된 오버드라이브와 디스토션 전달 함수를 구현하여 DSP보드에 집어 넣고 소리를 들어보았는데 그냥 뭉툭하고 고장난 앰프와 같은 소리만 날뿐, 내 싱글픽업 기타로는 하드록이나 헤비메탈과 같은 멋진 소리를 만들어 낼 수가 없었다.
  Before start, I've gathered useful methods, theories, implementations and examples of the digital audio signal processing for audio FX and I've found a book titled 'DAFX: Digital Audio Effects'[2] which is frequently commented at the replies or answers from the web. I just read only a chapter about overdrive and distortion wave-shaping and I expected it should be easy to implement because of very simple tranfer function of the overdrive and distortion introduced in the book. BUT, It's my big misjudgment. I've been struggling to make suitable distorted sound through lots of trial and errors and I've noticed that there are more and more than the simple distortion tranfer function.

  인터넷에서 찾을 수 있는 온갖 종류의 오버드라이브, 디스토션, 퍼즈 전달 함수들을 모조리 구하고 구현하여 소리를 들어 보았으나, 이득 (Gain)값을 올리면 그냥 뭉개지는 소리만 날 뿐이었다. 그렇게 시간만 흘려보내다 나와 같은 고민을 하던 사람의 꽤 오래전 글을 발견하였다[3]. 해당 글의 댓글중 Paul Chana의 짧지만 눈에 띄는 답변이 있었다. 'Upsampling' 2배 오버 샘플링이면 만족스럽다는 의견이 있어, 간단한 선형 보간 기법의 x2 오버샘플링 적용 후 디스토션 전달 함수를 거친 다음, 다시 원래 샘플링 속도로 돌려보니 완벽하지는 않으나 그래도 뭉툭한 소리가 상당히 개선 되었다. 비디오 게임 할 때만 눈에 보이던 안티 얼라이어싱 (Anti-Aliasing)을 소리로 직접 경험한 계기가 되었다.
  To make right sound, I've tried almost every transfer functions and wave-shaping methods from the web but, I could not escape from chubby and fat sound with high distortion gain, A.K.A. ALIASED sound. I didn't noticed that chubby/fat sound is the aliased one until Paul Chana's short reply[3]. 'UPSAMPLING'. Yes, to solve the aliasing problem, anti-aliasing method is needed. Through that comment, I've implemented x2 oversampling with simple linear interpolation and I found that the sound quality was improved very well. But it could not perfectly close my sound needs issue. No luck with digital filters and my project was stucked for a while.

  그런데, 아직도 여전이 뭔가 부족하다. 중/고음 영역대에서 쏴대는 소리가 많이 아쉬웠다. 또 다시 한 동한 진척이 없었다. 디지털 필터를 이리저리 넣어 봐도 딱히 마음에 들 정도의 개선은 이루어 지지 않았다. 그러다 찾게된 인터넷 동영상[4]에서 힌트를 얻었다. 동영상 내용중 'High Crossover Distortion'이라고 표현한 부분인데 내게 부족했던 그 소리를 만들어 주고 있었다. 구현을 위해 'High Crossover Distortion'과 관련된 이론을 찾아 봤으나, 정형화 되거나 일반화된 이론은 찾을 수가 없었다. 그래서 sin() 함수를 적용하여 직접 구현 했다. 동영상에서 소개된것 처럼 일정 이하의 낮은 신호에 대해 높은 이득을 주고, 그 이상의 신호에 대해서는 디스토션 전달 함수를 적용하면 되는데 'YetAnotherElectronicsChannel'[5]과 같이 Threshold 기법으로 이득을 적용하는 것 보다는 sin() 함수를 적용하면, sin()함수 특성상 신호가 0에 가까워 지면 이득값도 0으로 수렴하게 되므로, 싱글픽업 특유의 험 노이즈 (Hum Noise)와 Threshold 근처에서 발생하는 특유의 끊기는 소리를 최소화 할 수 있다.
  At last, I found a good video[4]. 'High Crossover Distortion' is the keyword of that contents. I could not found some general theory about the 'High Crossover Distortion' but, some guy[5] was presented implementation of the 'High Crossover Distortion' with simple threholding method. I implemented this 'High Crossover Distortion' with sin() function for distortion gain instead. If audio signal is going to zero, sin() function based gaining is also converged to the zero. This charicteristic makes low hum noise and stuttering sound at the near-threshold, in spite of high gain with single pickup guitar. [Fig. 2] shows my distortion implementation in C-code. Small audio signal is amplitude by sin() function and higher signal is transfered by distortion transfer function [Eq. 2] introduced in lecture [6]. Standard sin() function that is supported by C-runtime math library is a kind of costly one and it's not suitable for realtime digital signal processing. So I used fast apporoximated and simple sin() function which was introduced by 'javidx9'[7]. [Fig. 3] shows the C-codded fast apporoximated sin() function.

  그렇게 정리되고 구현된 나의 디스토션 코드는 [Fig. 2]과 같다. sin() 함수는 시간소모가 많이 발생되는 함수 이므로, 기본 개발 도구에서 지원하는 수학 라이브러리는 실시간 오디오 DSP에는 거의 쓸 수가 없고, 'javidx9'[7]이 소개한 고속 근사 sin() 함수를 [Fig. 3]과 같이 구현하여 적용했다. 큰 신호에 대한 디스토션 전달 함수는 한 대학 강좌[6]에서 소개한 [Eq. 2]을 전달 함수로 적용 하였다. 그렇다고 해서 고가의 멀티이펙터나 고급 디스토션/퍼즈 만큼의 소리가 바로 나지는 않았다. 개선은 됐지만 여전히 뭉툭하고 답답한 소리가 남아 있었다. 섞여있는 뭉툭한 Aliased-Sound 제거를 위해 디스토션 처리 전과 후에 고주파 대역 통과 필터 (High Pass Filter)를 적용해 보니, 더욱 개선된 소리를 내어주었다. 구현된 전체 디스토션 이펙터를 블럭 다이어그램으로 표현하면 [Fig. 4]과 같다. 딜레이 효과는 메모리에 딜레이가 필요한 만큼 저장하고, 현재 입력된 오디오 신호와 메모리에 저장된 과거의 신호를 적절히 섞어 주면 구현은 간단하다. 메모리에 저장된 오디오 신호를 활용해 고속 푸리에 변환 (FFT - Fast Fourier Transform)을 적용하여 기타줄 튜너기능도 함께 넣어 주었는데, 이게 또 그리 녹록치가 않았다. FFT로 분석하고 최대치 주파수만 뽑아내면 될 줄 알았는데 4, 5, 6번줄의 경우 기본 주파수보다 하모닉 주파수의 크기가 더 커서 보통 Autocorrelation 기법과 같은 어느정도 정형화된 Pitch Detection 알고리즘을 적용해야 했다. 정형화된 고급 알고리즘 대신, 간단하게 1~150Hz구간에서 FFT 변환 최대치, 150~350Hz 구간에서 최대치 2가지를 구하게되면 1~150Hz구간은 4, 5, 6번 기타줄 튜닝이 가능하고, 150~350Hz구간은 기타줄 1, 2, 3번줄 튜닝이 가능함을 실험을 통해 확인하고 FFT와 연동하여 비교적 단순하게 만들어 넣었다. CPU여유가 좀 있는듯 하여 만드는 김에 계획에 없던 노이즈 게이트도 만들어 추가해 주었다. 주요 알고리즘 구현이 얼추 되었으니, 다음 사진들 처럼 껍데기까지 만들어 완성 시켰다. 입력 신호 샘플링은 48 kHz이다.
  Almost done, but still there are little chubby and fat sound. So I added high pass digital filter for the distortion input and output and sound was improved enough for me since the HPF limits large energe signal. The Delay effect is quit simple. Just store the audio signal into RAM and mix it with currently processed audio signal. The audio signals in RAM also can be used for other purpose such as guitar tuner with FFT (Fast Fourier Transform). You may need well known general Pitch Detection algorithm such as Autocorrelation method since peak detection is not suitable with 4th, 5th and 6th string because of larger harmonics magnitute than fundamntal frequency. I solved this problem with a simple frequency divide method without sophisticated algorithm. If you find peak magnitude in range 1~150Hz, the pitch of the 4th, 5th and 6th strings are can be easly separated and detected with simple max detection method. In range 150~350Hz, the pitch of the 1st, 2nd and 3rd strings are also can be detected. [Fig. 4] shows my stompbox's signal path/processing diagram and sampling frequency is 48 kHz.

[Fig. 2] My Distortion Code

[Fig. 3] Fast sin() Function

[Fig. 4] Signal Processing Diagram

[Fig. 5] Heatsink Attatched

[Fig. 6] Assembling

[Fig. 7] Final Result

[Fig. 8] Powered On

[Fig. 9] LCD Display

[Fig. 10] My Luxury Guitar Amplifier

  소리를 들어볼 시간. 소리 녹음은 [Fig. 10]의 내 고급 기타 앰프에 자작한 꾹꾹이를 연결하고 촬영한 카메라 마이크로 그냥 녹음했다. 카메라 세팅하고 녹화하고 테스트하고 편집하고 유튜브 올리고... 어우 힘들어. 유튜버님들 대단함.
  It's time to play. Sound is simply recorded through my camera microphone with my luxury guitar amplifier [Fig. 10].

[Fig. 11] Demo. Sound

* References
[4] FL Studio Guru, Fruity Waveshaper and Distortion: https://www.youtube.com/watch?v=1L9djVLaUSU
[5] YetAnotherElectronicsChannel, Guitar Distortion Effect: https://www.youtube.com/watch?v=azLQf4aLv9w
[6] A Guitar Distortion Pedal Using The Stanford DSP Sheild: https://web.stanford.edu/class/ee264/projects/EE264_w2015_final_project_herman.pdf
[7] javidx9, Fast and Simple Approximation of Sine Function: https://www.youtube.com/watch?v=1xlCVBIF_ig