2014-10-31 8 views
2

음악 프로그램을 처음부터 프로그램하고 싶습니다. 큰 목표 : 예. 나는 아무 것도 끝낼 의도가 없다. 이것은 주로 학습을위한 개인 프로젝트입니다. : P오디오 합성 모범 사례

첫 번째 단계는 발진기와 계측기를 구축하는 것입니다. 악기는 아마도 오실레이터와 필터 (그리고 엔벨로프 + 이펙트)의 조합 일 것입니다. 자, 내 첫 번째 질문은 : 웨이브 제너레이터를 어떻게 구축해야합니까?

악기 X와 다른 음표를 연주하는 트랙이 있다고 가정합니다.이 음표를 "미리 렌더링"하는 것이 가장 좋습니다. 따라서 웨이브 함수를 실행하여 웨이브를 나타내는 숫자 배열을 생성하려면 선행 비용을 지불해야합니다. 44.1KHz의 샘플 속도로이 작업을 수행한다고 가정 할 때 악기 당 초당 44.1k 항목의 배열을 갖게됩니다.

이 질문 자체는 언어에 구애받지 않는다고 생각합니다. 하지만 브라우저에서 실행하기 때문에 JavaScript를 사용할 계획입니다.

답변

1

오디오는 곡선 일뿐입니다. 따라서 오실레이터를 빌드하려면 곡선을 출력하는 데 알 고가 필요합니다. 아날로그가 아닌 디지털 방식의 소프트웨어는 곡선이 오디오 곡선의 순간 높이 인 시간의 샘플 (샘플)로 정의해야합니다. 일반적으로 이러한 샘플은 초당 44100 회 발생합니다. 헤르츠.

checkout 웹 오디오 API - 놀라 울 정도로 강력하고 매우 지원 될 것입니다. 그냥 유연성 체크 아웃 구글 관계자 내부자 다른 오디오 위젯 사이

Web Audio Playground 
http://webaudioplayground.appspot.com/ 

에 의해 쓰여진이 데모의 감사의 마음을 얻기 위해,이 블랙 박스 오실레이터를 제공, 아직 당신은 자신의 롤과 합성 또는 파일 기반의 오디오를 렌더링 할 수 있습니다 실시간 데이터. 당신이이 노드

다음

을 연결하여 구축

function setup_onaudioprocess_callback(given_node) { 

    given_node.onaudioprocess = (function() { 

     return function(event) { 

      if (allow_synth) { 

       // console.log('inside main_glob callback onaudioprocess BUFF_SIZE ', BUFF_SIZE); 

       var synthesized_output_buffer; 

       // stens TODO - how to pass in own buffer instead of being given object: out so I can do a circular ring of such buffers 

       synthesized_output_buffer = event.outputBuffer.getChannelData(0); // stens TODO - do both channels not just left 

       var phi = 0, 
        dphi = 2.0 * Math.PI * given_node.sample_freq/
        given_node.sample_rate; 

       for (var curr_sample = 0; curr_sample < given_node.BUFF_SIZE; curr_sample++, phi += dphi) { 

        synthesized_output_buffer[curr_sample] = Math.sin(phi); 
       } 

       given_node.sample_freq *= given_node.freq_factor; 

       if (given_node.sample_freq < 
        given_node.MIN_FREQ) { 

        given_node.freq_factor = given_node.increasing_freq_factor; 

       } else if (given_node.sample_freq > given_node.MAX_FREQ) { 

        given_node.freq_factor = given_node.decreasing_freq_factor; 
       } 

       // --- 

       audio_display_obj.pipeline_buffer_for_time_domain_cylinder(synthesized_output_buffer, 
        BUFF_SIZE, "providence_2"); 
      } 
     }; 

    }()); 
} 

가이 노드에 관련하여 사용되는 (오실레이터) 음성을 합성하는 데 사용되는 콜백의 정의입니다 - 모듈 형 각각의 구성 요소는 노드라고 createScriptProcessor

function init_synth_settings(given_node, g_MIN_FREQ, g_MAX_FREQ, g_BUFF_SIZE, g_decreasing_freq_factor, g_increasing_freq_factor) { 

    given_node.MIN_FREQ = g_MIN_FREQ; 
    given_node.MAX_FREQ = g_MAX_FREQ; 

    given_node.sample_freq = given_node.MIN_FREQ; // Hertz 
    given_node.BUFF_SIZE = g_BUFF_SIZE; 

    given_node.decreasing_freq_factor = g_decreasing_freq_factor; 
    given_node.increasing_freq_factor = g_increasing_freq_factor; 
    given_node.freq_factor = g_increasing_freq_factor; 
} 

var this_glob_01 = audio_context.createScriptProcessor(BUFF_SIZE, 1, 1); 

init_synth_settings(this_glob_01, 20, 300, BUFF_SIZE, 0.98, 1.01); 

setup_onaudioprocess_callback(this_glob_01); 

를 사용하여 생성이 고비

+0

놀이터에 연결해 주셔서 감사합니다. 포스트의 나머지는 근본적으로 나의 질문의 rehash이었다. 어쩌면 내가 분명하지 않았을까요? 실제 구현 방법에 대한 팁을 찾고있었습니다. :) – simme

+0

코드를 보내 주셔서 감사합니다! 그러나 당신은 이것을 어디에서 발견하고 있습니까? https://github.com/cwilso/WebAudio/에서? 내가 찾지 못해서 눈이 멀었나요? : 코드 위의 P – simme

+0

은 내 첫 번째 JavaScript 프로젝트에서 가져온 것입니다. https://github.com/scottstensland/webgl-3d-animation/blob/master/src/webaudio_tooling.js –

1

말을 통해 당신을 얻을합니다 이것을 44.1KHz의 샘플 레이트로 처리하고 싶습니다. 즉, 악기 당 초당 44.1k 항목의 배열을 갖게 될까요?

정확히 44.1k 샘플을 플로트 또는 바이트 형식으로 사용합니다 (사용하는 언어에 따라 다름).

RATE = 44100 
frequency = 440 
for(i = 0; i < RATE; i++){ 
    array[i] = sin(i*2*PI*frequency/RATE); 
} 
0
#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 

#define PI 3.141592 

int main(void){ 

double RATE = 44100; 
double frequency = 440; 
double Amp=16384;//amplitude of signal 
FILE *file; 
double data; 
    file=fopen("dummyf.pcm", "w"); 

for(double i = 0; i < RATE; i++){ 
    data = Amp*sin(i*2*PI*frequency/RATE); 
    fputc(data, file); 
} 

fclose(file); 

return 0; 
} 

내가 파일을 사용하여 데이터를 기록하기 위해 다른 솔루션을 시도하려는 :

여기 44.1kH에서 부동 기반 샘플 1 초 사인파를 생성하는 일부 의사입니다. 메모리에 큰 배열을 만들 필요가 없다는 장점이 있습니다. 함수로 자신의 데이터를 만들고 메모리보다 pcm 파일에 저장하는 편이 쉽습니다.

LE : fx를 사용하기 때문에 DirectX DirectMusic을 대신 사용해야합니다.많은 악기의 합성.

LE2 : 내 프로그램은 지금은 이전 답변자가 지적했듯이

+0

정말 이상한 코드입니다. 'int main'이어야하고 배열 [0]을 사용하지 않고 array [2]를 디스크에 씁니다. 존재하지 않으면 디스크에'free'를 호출합니다. 'malloc'에 의해 할당 된 파일을 열 수 있는지를 확인하지 않고'int i'와'RATE'를 비교합니다. 이것은'double'입니다 ... – MSalters

1

예상대로 작동하지 않습니다 당신은 출력에 일련의 값을 C에서 간단한 프로그램 (또는 그 문제에 대한 모든 언어를) 쓸 수 있습니다 사운드 샘플 또는 사운드 웨이브 포인트를 나타냅니다. 이 값을 텍스트 파일에 쓰면 sox (http://sox.sourceforge.net/)과 같은 프로그램을 사용하여이 파일을 .wav 파일로 변환 할 수 있습니다. 그런 다음 컴퓨터에서 wav 파일을 재생하고 스피커를 통해 음파를들을 수 있습니다.