목록개발 공부 (130)
음악, 삶, 개발
Juce 로 미디이펙트를 만들기위한 가장 필수적인 지식들과 예제코드들을 정리해보려한다. 이 포스트는 VST3 플러그인 기준이며, Standalone 이나 iOS 는 해당되지않는다. Max 에서는 미디 메세지의 움직임은 모두 MSP object 가 아닌, Max object 에서 일어난다. 하지만 Juce 는 그렇지않다. 미디의 입,출력이 audio thread, 즉 processBlock() 안에서 일어난다. void processBlock(juce::AudioBuffer& audioBuffer, juce::MidiBuffer& midiBuffer) override { /* 이안에서 지지고볶고 하는것이다. */ } processBlock() 함..
samplePerBeat : 1 beat 당 몇개의 sample 들이 있는지 계산하기 beatPerSample : 한 sample 이 얼마만큼의 beat 를 나타내는지 계산하기 위의 samplePerBeat 로, 1 beat 에 얼마만큼의 sample 들이 있는지 알수있기때문에, 이 결과를 다시 1 나눠주면 하나의 sample 이 나타내는 beat 값을 알수있다. note point 는 buffer 의 sample index 이다. BPM 에 따라, note point 를 나타낼 sample 의 index 가 달라진다.
내가 VST 개발에 뛰어든 중요한 이유중 하나는 나만의 시퀀서를 가지고싶어서였다. 내가 말하는 시퀀서는 모든 DAW 가 가지고있는 Piano Roll 이다. Piano Roll 을 만드는것은 매우 거대한 문제이다. 우리가 자동차를 운전하는것은 어렵지않지만, 자동차를 만드는것은 상상할수없는 난이도일것이다. 이 논리가 Piano Roll 을 만드는데에도 적용될것이라는 다짐을 일단 해야한다. 사용자가 DAW 에서 보는것은 결국 GUI 이다. 사람들은 자신이 더블클릭하여 노트를 추가하면 노트 GUI 가 보여지고 이 노트는 연주된다라는 사실을 알고있다. 하지만 개발자의 입장에서 생각해보자. 실질적으로 미디 노트가 악..
이제 남은 문제는 아래와 같다. 4. 어떻게 나의 파라미터를 GUI 에 연결할수있는지? 5. 어떻게 나의 파라미터 값을 이 GUI 로 변경할수있는지? 위 문제들을 마지막으로 해결하기전에 아래의 강좌를 무조건 시청한다. Controlling Audio Parameters with ValueTree Attachments 위의 강좌는 파트1, 파트2 내용을 모두 다루는데, 우리는 이미 앞선 포스트들로 학습을 했기때문에 이해하는데 무리가 없을것이다. 4. 어떻게 나의 파라미터를 GUI 에 연결할수있는지? 앞서 우리는 juce::AudioProcessor 의 서브 클래스에 코드를 작성하는 작업을 하였다. 이제부터는 juce::AudioProcessorEditor 의 서브 클래스에 코..
앞선 포스트에서 우리의 고민 사항은 아래와 같았다. 1. 어디에 나의 파라미터를 추가할것인지? 2. 어떻게 나의 파라미터를 추가할수있는지? 3. 어떻게 나의 VST 출력은 이 파라미터 값을 반영할수있는지? 4. 어떻게 나의 파라미터를 GUI 에 연결할수있는지? 5. 어떻게 나의 파라미터 값을 이 GUI 로 변경할수있는지? 1. 어디에 나의 파라미터를 추가할것인지? 2. 어떻게 나의 파라미터를 추가할수있는지? 를 해결하여 아래의 코드를 완성했다. class VSTPlugin : public juce::AudioProcessor { public : VSTPlugin() : apvts(*this, nullptr, juce::Identifier("APVTS"), createParams()) ..
위의 사진을 보면, 내가 노브를 돌렸을때 하단의 값이 변하고, 하단의 값을 움직이면 위의 노브가 변한다. 우리는 결국 이와 같은것을 하고싶다. 저렇게 VST 에 내가 원하는 이름의 파라미터를 추가하고싶다. 그뿐만 아니라, 내가 만든 GUI 로 저 파라미터를 조절하고싶다. 사용자의 느낌으로 얼핏보았을때는, 흠 쉬운데? 할수있지만 개발자의 입장에서는 불행히도 그렇지않다... 음식도 먹는게 쉽고, 만드는게 훨씬 어렵지않은가.. 여러가지 스탭들이 합해야 위의 그림같은 상황을 연출할수있다. 내가 앞선 포스트들에서 audio thread 와 message thread 를 지속적으로 이야기한 이유가 결국 여기에 있다. gui thread (즉, message t..
이 부분에 대해, 추가적인 연구가 필요한데 일단 Nathan 과 Peter 가 얘기해준 부분을 남겨놓는다. 추후 공부하면서 이 포스팅은 다시 업데이트 하는걸로. Nathan Quick tip that my be helpful to you. If you set JUCE_ENABLE_REPAINT_DEBUGGING to enabled in the projucer under the juce_gui_basics module, then you can see when areas of the screen are being redrawn. I have found that using a child component for drawing ui elements means that it will only redraw the ..
Debug 모드가 2배정도 Relase Mode 보다 높다. 따라서, CPU 사용량을 정확히 측정하려면 Release Mode 로 VST3 를 컴파일해야한다.
아래 포스팅한 오디오 thread 와 메세지 thread 에 대한 글들을 숙지하였다면, 이제는 먼가를 그려볼 시간이다. PPQ 의 값을 사용하여야한다. 공식문서 ppq 값을 가지고있는 클래스로써, AudioProcessor 클래스의 함수 getPlayHead() 함수를 이용하여, 오디오 thread, 즉 processBlock() 안에서 가져와야한다. 아래는 AudioProcessor 클래스의 getPlayHead() 에 대한 설명이다. 반드시 processBlock() 에서만 호출하라고 되어있다. getPlayHead() 는 AudioPlayHead 객체의 포인터를 return 한다. 이 포인터로 juce::AudioPlayHead::CurrentPositionInfo 객체를 얻는다. void proc..
앞선 포스팅들에서, processBlock() 과 audio thread, gui thread 에 대해 알아보았다. audio thread 와 message thread 를 공유하는 변수를 사용하기위해서는 std::atomic 에 대해 알아야한다. 아래의 링크들을 먼저 읽어보도록 한다. [C++11] atomic cplusplus 닷컴 cplusplus 닷컴 위의 링크에서는 아래와 같이 설명하고있다. Atomic types are types that encapsulate a value whose access is guaranteed to not cause data races, and can be used to synchronize memory accesses a..