2011-12-23 31 views
7

Dựa trên những gì tôi đọc, tôi đã thực hiện thuật toán tổng hợp âm thanh FM. Tôi không chắc liệu tôi có làm đúng không. Khi tạo một công cụ phần mềm synth, một hàm được sử dụng để tạo ra một bộ dao động và một bộ điều biến có thể được sử dụng để mô-đun tần số của bộ dao động này. Tôi không biết nếu tổng hợp FM được cho là chỉ hoạt động để điều chỉnh sóng sin?Thuật toán tổng hợp điều chế tần số

Thuật toán lấy hàm sóng của công cụ và chỉ số và tỷ số điều biến cho bộ điều biến tần số. Đối với mỗi lưu ý phải mất tần số và lưu trữ các giá trị pha cho các sóng mang và bộ điều biến dao động. Bộ điều biến luôn sử dụng sóng sin.

Đây là thuật toán trong giả:

function ProduceSample(instrument, notes_playing) 
    for each note in notes_playing 
     if note.isPlaying() 
      # Calculate signal 
      if instrument.FMIndex != 0 # Apply FM 
       FMFrequency = note.frequency*instrument.FMRatio; # FM frequency is factor of note frequency. 
       note.FMPhase = note.FMPhase + FMFrequency/kGraphSampleRate # Phase of modulator. 
       frequencyDeviation = sin(note.FMPhase * PI)*instrument.FMIndex*FMFrequency # Frequency deviation. Max deviation is a factor of the FM frequency. Modulation is done by a sine wave. 
       note.phase = note.phase + (note.frequency + frequencyDeviation)/kGraphSampleRate # Adjust phase with deviation 
       # Reset the phase value to prevent the float from overflowing 
       if note.FMPhase >= 1 
        note.FMPhase = note.FMPhase - 1 
       end if 
      else # No FM applied 
       note.phase = note.phase + note.frequency/kGraphSampleRate # Adjust phase without deviation 
      end if 
      # Calculate the next sample 
      signal = signal + instrument.waveFunction(note.phase,instrument.waveParameter)*note.amplitude 
      # Reset the phase value to prevent the float from overflowing 
      if note.phase >= 1 
       note.phase = note.phase - 1 
      end if 
     end if 
    end loop 
    return signal 
end function 

Vì vậy, nếu tần số của lưu ý là tại 100Hz, các FMRatio được thiết lập ở mức 0,5 và FMIndex là 0,1 nó nên sản xuất tần số đi giữa 95Hz và 105Hz trong một 50Hz chu kỳ. Đây có phải là cách làm đúng hay không. Các thử nghiệm của tôi cho thấy rằng nó không phải lúc nào cũng đúng, đặc biệt là khi điều chỉnh cưa và sóng vuông. Liệu có thể điều chỉnh các sóng cưa và sóng vuông như thế này hay chỉ là sóng sin?

này là việc thực hiện trong C và CoreAudio:

static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){ 
    AudioSynthesiser * audioController = (AudioSynthesiser *)inRefCon; 
    // Get a pointer to the dataBuffer of the AudioBufferList 
    AudioSampleType * outA = (AudioSampleType *) ioData->mBuffers[0].mData; 
    if(!audioController->playing){ 
     for (UInt32 i = 0; i < inNumberFrames; ++i){ 
      outA[i] = (SInt16)0; 
     } 
     return noErr; 
    } 
    Track * track = &audioController->tracks[inBusNumber]; 
    SynthInstrument * instrument = (SynthInstrument *)track; 
    float frequency_deviation; 
    float FMFrequency; 
    // Loop through the callback buffer, generating samples 
    for (UInt32 i = 0; i < inNumberFrames; ++i){ 
     float signal = 0; 
     for (int x = 0; x < 10; x++) { 
      Note * note = track->notes_playing[x]; 
      if(note){ 
       //Envelope code removed 
       //Calculate signal 
       if (instrument->FMIndex) { //Apply FM 
        FMFrequency = note->frequency*instrument->FMRatio; //FM frequency is factor of note frequency. 
        note->FMPhase += FMFrequency/kGraphSampleRate; //Phase of modulator. 
        frequency_deviation = sinf(note->FMPhase * M_PI)*instrument->FMIndex*FMFrequency; //Frequency deviation. Max deviation is a factor of the FM frequency. Modulation is done by a sine wave. 
        note->phase += (note->frequency + frequency_deviation)/kGraphSampleRate; //Adjust phase with deviation 
        // Reset the phase value to prevent the float from overflowing 
        if (note->FMPhase >= 1){ 
         note->FMPhase--; 
        } 
       }else{ 
        note->phase += note->frequency/ kGraphSampleRate; //Adjust phase without deviation 
       } 
       // Calculate the next sample 
       signal += instrument->wave_function(note->phase,instrument->wave_parameter)*track->note_amplitude[x]; 
       // Reset the phase value to prevent the float from overflowing 
       if (note->phase >= 1){ 
        note->phase--; 
       } 
      } //Else nothing added 
     } 
     if(signal > 1.0){ 
      signal = 1; 
     }else if(signal < -1.0){ 
      signal = -1.0; 
     } 
     audioController->wave[audioController->wave_last] = signal; 
     if (audioController->wave_last == 499) { 
      audioController->wave_last = 0; 
     }else{ 
      audioController->wave_last++; 
     } 
     outA[i] = (SInt16)(signal * 32767.0f); 
    } 
    return noErr; 
} 

Answers được rất nhiều đánh giá cao.

+1

Đây có thể là một câu hỏi hay cho http://dsp.stackexchange.com (hoặc có thể http://avp.stackexchange.com). – mtrw

+0

Được rồi, tôi sẽ thử. Cảm ơn! –

Trả lời

2

Cuối cùng, tôi quyết định sử dụng điều chế pha. Tôi phát hiện ra nhiều nhà tổng hợp sử dụng điều chế pha ngay cả khi chúng được gắn nhãn với FM.

Nó rất đơn giản để thực hiện:

signal += wave_function(note_phase * note_frequency/sample_rate + fm_index * sin(note_phase * fm_frequency * pi/sample_rate))*note_amplitude 
+0

Bạn có sẵn lòng trích dẫn bất kỳ tài nguyên nào bạn thấy hữu ích nhất không? Tôi đang có một số thành công tốt đẹp với tổng hợp FM 2-nhà điều hành, nhưng nhận được kết quả lập dị khi tôi cố gắng cascading 3 nhà khai thác trong loạt. Bạn đã sử dụng FM trong thời trang đó chưa? Tôi đã sử dụng phương trình bạn trích dẫn và người anh em họ FM của nó, nhưng kết quả là giống hệt nhau! –

3

Tốt câu hỏi, tôi sẽ cố gắng đưa ra một vài suy nghĩ/ý tưởng ...

Để trả lời câu hỏi chính của bạn, vâng đó là hoàn toàn tốt cho điều chỉnh dạng sóng khác hơn là sóng sin. Trong thực tế, đó là những gì FM là tốt nhất. Điều chỉnh sóng sin cho đầu ra âm thanh rất nhàm chán, nhưng khi bạn nhập các dạng sóng phức tạp hơn với cùng một điều chế, bạn sẽ nhận được nhiều kết quả thú vị hơn. FYI (trong trường hợp bạn chưa biết), synth FM nổi tiếng nhất có lẽ là Yamaha DX7 là cuộc cách mạng trong ngày của nó (và cũng là một trong những synths đầu tiên với MIDI).

Điều khác cần nói đến là tổng hợp FM là khởi đầu của thời đại kỹ thuật số, do đó dạng sóng được tạo ra bằng kỹ thuật số và do đó sử dụng dạng sóng tinh vi hơn sóng sin/vuông/tam giác để tạo ra âm thanh thú vị. Đây có thể là những gì bạn cần làm để có được âm thanh tốt hơn - thay vì chỉ tạo ra một sóng sin để điều chỉnh, sử dụng dạng sóng phức tạp.

Nhìn qua mã của bạn, có vẻ như bạn đang thực hiện FM đúng cách. Tuy nhiên, tôi nghĩ rằng tần số điều chế thường được cố định chứ không phải là một phần của tần số ghi chú như trong mã của bạn. Nó có thể là giá trị cố gắng này và nhìn thấy nếu nó âm thanh giống như những gì bạn đang tìm kiếm.

Tôi hy vọng điều đó sẽ giúp ích một chút.

+0

Cảm ơn câu trả lời. Tôi quyết định đi cho một giai đoạn điều chế cuối cùng. –

6

mắt đỏ:

Để trả lời câu hỏi chính của bạn, vâng đó là hoàn toàn tốt để điều chỉnh dạng sóng khác hơn là sóng sin. Trong thực tế, đó là những gì FM là tốt nhất. Điều chỉnh sóng sin cho đầu ra âm thanh rất nhàm chán, nhưng khi bạn nhập các dạng sóng phức tạp hơn với cùng một điều chế, bạn sẽ nhận được nhiều kết quả thú vị hơn.

Đây là cách tốt nhất để đơn giản hóa và có thể hoàn toàn sai. Điều chỉnh sóng sin với sóng sin là hoàn toàn có khả năng tạo ra một loạt các âm thanh phức tạp và không "nhàm chán".

Ngược lại, các dạng sóng phức tạp nhân số lượng các dải rộng kết quả một cách ồ ạt và làm cho kết quả dự đoán khó đạt được hơn nhiều. Hầu hết các tài liệu về FM - mà thực sự là điều chế PHASE gần như tương đương (PM) trong nhiều trường hợp phổ biến bao gồm "the" "FM" của Yamaha - chỉ liên quan đến sóng sin.

FYI (trong trường hợp bạn chưa biết), synth FM nổi tiếng nhất có lẽ là Yamaha DX7 là cuộc cách mạng trong ngày (và cũng là một trong những synth đầu tiên với MIDI).

Điều khác đề cập đến là tổng hợp FM là khởi đầu của thời đại kỹ thuật số nên dạng sóng được tạo ra bằng kỹ thuật số và do đó sử dụng dạng sóng phức tạp hơn so với sóng/vuông/tam giác sin để tạo ra những âm thanh thú vị."

Điều này hoàn toàn sai lệch, DX7 và nhiều FM đầu tiên - trên thực tế, PM - synths của Yamaha chỉ cung cấp sóng sin, nhưng như tôi đã nói ở trên, chúng vẫn có khả năng nhiều, không nhiều "âm thanh" Không có "dạng sóng phức tạp hơn" đã được tham gia.

Chỉ sau đó Yamaha thêm các dạng sóng khác, và tiện ích của chúng có phần que stionable khi so sánh với khả năng dự đoán của sidebands được tạo ra bởi sóng sin, như tôi đã nói ở trên.

Đây có thể là những gì bạn cần phải làm để có được một âm thanh tốt hơn -. Chứ không chỉ tạo ra một làn sóng sin để điều chỉnh, sử dụng dạng sóng phức tạp"

Hoặc chỉ cần sử dụng sóng sin với sự sắp xếp tốt và Sự kết hợp giữa các thông số (tỷ số, chỉ số, vv)

Thực tế là FM/PM có sóng sin không ngay lập tức tạo ra chất lượng studio - hoặc có thể giống như kết quả tương tự cho nhiều người dùng không cho biết không thể làm như vậy.

Các vấn đề liên quan