ফ্রিকোয়েন্সি মডুলেশন সংশ্লেষ অ্যালগরিদম


9

আমি যা পড়েছি তার উপর ভিত্তি করে, আমি এফএম শব্দ সংশ্লেষণের জন্য একটি অ্যালগরিদম তৈরি করেছি। আমি ঠিক করেছিলাম কিনা তা নিশ্চিত নই। একটি সফ্টওয়্যার সিন্থ ইনস্ট্রুমেন্ট তৈরি করার সময় একটি ফাংশন একটি দোলক উত্পন্ন করতে ব্যবহৃত হয় এবং এই দোলকের ফ্রিকোয়েন্সিটি মডিউল করার জন্য একটি মডিউলেটর ব্যবহার করা যেতে পারে। আমি জানি না যে এফএম সংশ্লেষণ কেবল সাইন ওয়েভগুলি সংশোধন করার জন্য কাজ করবে?

অ্যালগরিদম ফ্রিকোয়েন্সি মডুলেটারের জন্য যন্ত্র তরঙ্গ ফাংশন এবং মডিউলের সূচক এবং অনুপাত নেয়। প্রতিটি নোটের জন্য এটি ফ্রিকোয়েন্সি গ্রহণ করে এবং ক্যারিয়ার এবং মডুলেটর দোলকগুলির জন্য পর্বের মান সংরক্ষণ করে। মডুলেটর সর্বদা একটি সাইন ওয়েভ ব্যবহার করে।

এটি সিউডোকোডের আলগোরিদিম:

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 

সুতরাং যদি নোটটির ফ্রিকোয়েন্সি 100Hz এ থাকে তবে FMRatio 0.5 তে সেট করা থাকে এবং FMIndex 0.1 হয় এটি 50Hz চক্রের 95Hz এবং 105Hz এর মধ্যে যাওয়ার ফ্রিকোয়েন্সি তৈরি করতে হবে। এটি কি এটি করার সঠিক উপায়। আমার পরীক্ষাগুলি দেখায় যে এটি সর্বদা ঠিক শোনা যায় না, বিশেষত যখন করাত এবং বর্গাকার তরঙ্গগুলিকে সংশোধন করার সময়। এর মতো করাত এবং বর্গাকার তরঙ্গগুলি সংশোধন করা ঠিক কি এটি কেবল সাইন ওয়েভগুলির জন্য?

এটি সি এবং কোর অডিওতে বাস্তবায়ন:

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;
}

উত্তরগুলি খুব প্রশংসা করা হয়।


3
আমি আপনাকে এই প্রশ্নটি অনুসরণ করে আলোচনাগুলি পড়ার পরামর্শ দেব । এখানে আপনি অন্য প্রশ্নের মতো ফ্রিকোয়েন্সিতে হঠাৎ ট্রানজিশন করছেন না, এফএম সিগন্যালে ধাপের ধারাবাহিকতা বজায় রাখা খুব গুরুত্বপূর্ণ এবং এফএম সিগন্যালটি মডিউলিং ওয়েভফর্ম নির্বিশেষে পর্যায়-অবিচ্ছিন্ন কিনা তা নিশ্চিত করে নিন, সাইনোসয়েডাল বা স্যাতোথ বা স্কোয়ার ওয়েভ (ফ্রিকোয়েন্সিতে হঠাৎ পরিবর্তন এসেছে!), আপনাকে প্রচুর সমস্যা এড়াতে সহায়তা করবে।
দিলীপ সরোতে

3
আপনার কোডের বড় স্তূপ না পড়ে এটি জিজ্ঞাসা করার মতো: সমস্যাটি আসলে কী? আপনি বলছেন যে এটি কার্যকর কিনা তা আপনি নিশ্চিত নন। বিশেষত আপনাকে কী মনে করে যে এটি কাজ করছে না?
জেসন আর

উত্তর:


2

আপনি এখানে যা করছেন তা হচ্ছে ফেজ মডুলেশন। ইয়ামাহা ডিএক্স -7 এর মতো 'এফএম' সিনথগুলি এভাবেই কাজ করে। প্রায়শই সিন্থ অসিলেটরগুলি একটি সঙ্গীত স্কেলে সুর করা হয়, কোনও সরল লিনিয়ার Hz স্কেল নয়। সুতরাং পিচটি মডিউলিংয়ের ফলে সরাসরি অবাঞ্ছিত পিচ শিফট হয়, এজন্য পর্বের মড্যুলেশন আরও উপযুক্ত। আপনি যে কোনও তরঙ্গ আকারকে মডিউল করতে পারবেন, তবে আরও জটিল আকারগুলি আরও তাত্ক্ষণিকভাবে উরফ করবে। এমনকি একটি পরিমিত পাপ যদিও উপাধি দিতে পারে, সুতরাং এটি নিষিদ্ধ নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.