예제 #1
0
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
	
	if (y< TOP_MARGIN && x>LEFT_MARGIN) {
		for (unsigned int i = 0; i < horizontalOscilators.size(); i++) {//this goes through the horizontal oscillators checking if anyone has been clicked over.
			if(horizontalOscilators[i].checkOver(x, y)){
				setPressedOscilator(i, true);
				break;
			}
		}
		if (!bSelectedOscHor) {//in case that no oscillator was clicked then create a new one at the position of the mouse.
			horizontalOscilators.push_back(oscillator());
			horizontalOscilators.back().setup(x, y);
		}
	}else if(y>TOP_MARGIN && x<LEFT_MARGIN){
		for (unsigned int i = 0; i < verticalOscilators.size(); i++) {
			if(verticalOscilators[i].checkOver(x, y)){
				setPressedOscilator(i, false);	
				break;
			}
		}
		if (!bSelectedOscVert) {
			verticalOscilators.push_back(oscillator());
			verticalOscilators.back().setup(x, y);
		}
	}else {
		bScaleMouse=true;
	}
}
예제 #2
0
void writeStream(PaStream *handle, float frequency, float duration, float amplitude) {
  int i,j,dur, count = 0;
  dur = duration*44100/256;
  float index, index2, control, cr, *buf, *wave;
  cr = 44100/256;
  index = 0.f;
  buf = (float*) malloc(256*sizeof(float));
  wave = sine_table(2048, 0);
  for(j = 0;j < dur;j++){
    oscillator(buf, frequency+oscillator(&control,5.f,5.f, wave, &index2,2048, 1,cr),envelope(duration,cr,&count)*amplitude,wave,&index,2048,256,44100);
    Pa_WriteStream(handle, buf, 256);
  }
  free(buf);
  free(wave);
}
예제 #3
0
/*!
  \internal
  \fn void Bouncer::animate(QPainter *painter,SelectedItem *item,qreal percent)
*/
void Bouncer::animate(QPainter *painter,SelectedItem *item,qreal percent)
{
    GridItem *currentItem = item->current();
    if ( !currentItem ) {
        return;
    }
    int imageSize = currentItem->selectedImageSize();

    // Create an oscillator which will produce a sin wave whose lower bound is the
    // first parameter (i.e. the lowest dimension the image will take, and whose
    // upper bound is the second parameter (i.e. the highest dimension the image
    // will take).
    Oscillator oscillator(imageSize + minVariation * imageSize,
                          imageSize + maxVariation * imageSize,
                          frameMax, // upper bound of x
                          SPEED_FACTOR,
                          imageSize);

    // Ask the oscillator to produce a suitable width/height value for this stage
    // of the animation.
    int y = qRound(oscillator(percent*frameMax));
    if (((y-imageSize) % 2) != 0) {
        y -= 1;
    }

    painter->setRenderHint(QPainter::SmoothPixmapTransform);

    //lazy man's version of mipmapping
    if (y > imageSize) {
        if (!bigpixmap.isNull())
            draw(painter,bigpixmap,item,y,y);
    } else {
        const QPixmap &pixmap = currentItem->selectedPic();
        if ( !(pixmap.isNull()) ) {
            draw(painter,pixmap,item,y,y);
        }
    }
}
예제 #4
0
    void testMidiWithSimpleSquare() {
        Audio::init();

        Synth::Misc::SimpleSquare oscillator(Audio::SAMPLE_RATE, 10000);

        Midi::init();
        Midi::BasicMsg midiMsg;

        Display::clearScreen();
        Display::writeString("Display test!",0);
        Display::carryOutAllActionsInQueue();
        Time::delayS(0.5);
        Display::carryOutAllActionsInQueue();

        int16_t sample = 0;
        bool isActive = false;

        while(1){
            if(!Midi::getMsgIfAble(&midiMsg)){
                midiMsg.msgType = 0;
            } else {
                if (midiMsg.msgType == Midi::MSG_TYPE_NOTE_ON) {
                    if(midiMsg.dataBytes[1] != 0) {
                        oscillator.setPitch(Midi::gNotes[midiMsg.dataBytes[0]]);
                        isActive = true;
                        Display::writeCharacterAt('O', 1, 0);
                    } else {
                        isActive = false;
                        Display::writeCharacterAt('X', 1, 0);
                    }
                } else if(midiMsg.msgType == Midi::MSG_TYPE_NOTE_OFF){
                    isActive = false;
                    Display::writeCharacterAt('X', 1, 0);
                }
            }

            if(isActive) {
                sample = oscillator.getNextSample();
            }
            while(!Audio::attemptToOutputSample(sample)){};

            Display::carryOutActionsUntilInterval();
        }

    }
int main()
{
    snd_pcm_t *pcm = nullptr;
    snd_rawmidi_t *nanoKEY2 = nullptr;
    snd_rawmidi_t *nanoKONTROL2 = nullptr;

    try
    {
        // open audio device
        // BEHRINGER UCA222 ---> http://www.behringer.com/EN/Products/UCA222.aspx
        if( ::snd_pcm_open(
            &pcm,
            "hw:CODEC",
            SND_PCM_STREAM_PLAYBACK,
            0) )
        {
            throw std::runtime_error("snd_pcm_open error");
        }

        // set parameters
        if( ::snd_pcm_set_params(
            pcm,
            SND_PCM_FORMAT_S16,
            SND_PCM_ACCESS_RW_INTERLEAVED,
            1, // mono
            44100,
            0,
            20*1000) ) // 20ms
        {
            throw std::runtime_error("snd_pcm_set_params error");
        }

        // get buffer size and period size
        snd_pcm_uframes_t buffer_size = 0;
        snd_pcm_uframes_t period_size = 0;
        if( ::snd_pcm_get_params(
            pcm,
            &buffer_size,
            &period_size) )
        {
            throw std::runtime_error("snd_pcm_get_params error");
        }

        // allocate buffer
        std::vector<short> buffer(period_size);

        std::cout << "start ("
                  << "buffer_size=" << buffer_size << ", "
                  << "period_size=" << period_size << ")"
                  << std::endl;

        std::cout << "MIDI:" << std::flush;

        // open MIDI device
        // KORG nanoKEY2 ---> http://www.korg.co.jp/Product/Controller/nano2/nanoKEY.html
        if( ::snd_rawmidi_open(
            &nanoKEY2,
            nullptr,
            "hw:nanoKEY2",
            SND_RAWMIDI_NONBLOCK ) )
        {
            throw std::runtime_error("snd_rawmidi_open error");
        }

        // オシレータ作成
        blit_saw_oscillator oscillator(0.995, 44100);

        // open MIDI device
        // KORG nanoKONTROL2 ---> http://www.korg.co.jp/Product/Controller/nano2/nanoKONTROL.html
        if( ::snd_rawmidi_open(
            &nanoKONTROL2,
            nullptr,
            "hw:nanoKONTROL2",
            SND_RAWMIDI_NONBLOCK ) )
        {
            throw std::runtime_error("snd_rawmidi_open error");
        }

        // parameters
        double volume = 1.0;
        double cutoff = 400.0;
        double resonance = M_SQRT1_2;
        double low = 1.0;
        double band = 0.0;
        double high = 0.0;

        // Biquad Filter作成
        biquad_filter filter(cutoff, resonance, low, band, high);

        do{
            //--------------------
            // MIDI event process
            //--------------------
            do{
                // read MIDI input
                std::array<unsigned char, 3> midi_data = {};
                ssize_t midi_read_count = ::snd_rawmidi_read(nanoKEY2, midi_data.data(), midi_data.size());

                if( midi_read_count != (int)midi_data.size() )
                {
                    // no more data
                    break;
                }

                ::printf("\rMIDI message:0x%02x 0x%02x 0x%02x", midi_data[0], midi_data[1], midi_data[2]);
                ::fflush(stdout);

                if( midi_data[0] == 0x90/*note on*/)
                {
                    oscillator.trigger(midi_data[1], midi_data[2]);
                }
                else if( midi_data[0] == 0x80/*note off*/)
                {
                    oscillator.release(midi_data[1]);
                }
            }while(true);

            // key:control number / value:value
            std::map<unsigned char, unsigned char> ControlChangeMap;
            do{
                // read MIDI input
                std::array<unsigned char, 3> midi_data = {};
                ssize_t midi_read_count = ::snd_rawmidi_read(nanoKONTROL2, midi_data.data(), midi_data.size());

                if( midi_read_count != static_cast<int>(midi_data.size()) )
                {
                    // no more data
                    break;
                }

                ::printf("\rMIDI message:0x%02x 0x%02x 0x%02x", midi_data[0], midi_data[1], midi_data[2]);
                ::fflush(stdout);

                if( midi_data[0] == 0xb0/*control change*/){
                    // 最後の値のみを保持
                    ControlChangeMap[ midi_data[1] ] = midi_data[2];
                }

            }while(true);

            // update parameters
            for(const auto& key_value : ControlChangeMap)
            {
                unsigned char control_number = key_value.first;
                double value = static_cast<double>(key_value.second)/127;
                if( control_number == 0x10 /* knob1 */)
                {
                    volume = value;
                }
                else if( control_number == 0x11 /* knob2 */)
                {
                    cutoff = 40.0*(1.0-value) + 4000.0*value;
                }
                else if( control_number == 0x12 /* knob3 */)
                {
                    resonance = M_SQRT1_2*(1.0-value) + 20.0*value;
                }
                else if( control_number == 0x13 /* knob4 */)
                {
                    low = value;
                }
                else if( control_number == 0x14 /* knob5 */)
                {
                    band = value;
                }
                else if( control_number == 0x15 /* knob6 */)
                {
                    high = value;
                }
            }

            // フィルタの更新が必要か?
            auto isFilterUpdate = [](std::pair<unsigned char, unsigned char> key_value){
                unsigned char control_number = key_value.first;
                return control_number == 0x11 // knob2
                    || control_number == 0x12 // knob3
                    || control_number == 0x13 // knob4
                    || control_number == 0x14 // knob5
                    || control_number == 0x15;// knob6
            };
            if( std::any_of(ControlChangeMap.begin(), ControlChangeMap.end(), isFilterUpdate) )
            {
                // フィルタの更新(L/R)
                filter.update(cutoff, resonance, low, band, high);
            }

            //---------------
            // audio process
            //---------------
            for(short& s : buffer)
            {
                s = 1000.0 * filter.process( oscillator.process() );
            }

            //-------------
            // write audio
            //-------------
            if( ::snd_pcm_writei(pcm, buffer.data(), period_size) < 0 )
            {
                throw std::runtime_error("snd_pcm_writei error");
            }
        }while(true);

        std::cout << std::endl << "end" << std::endl;
    }
    catch(std::exception &ex)
    {
        std::cout << std::endl << "error:" << ex.what() << std::endl;
    }

    if(pcm != nullptr)
    {
        // close audio device
        ::snd_pcm_close(pcm);
    }

    if(nanoKEY2 != nullptr)
    {
        // close sound file
        ::snd_rawmidi_close(nanoKEY2);
    }

    if(nanoKONTROL2 != nullptr)
    {
        // close sound file
        ::snd_rawmidi_close(nanoKONTROL2);
    }

    return 0;
}
/*
 * xsynth_voice_render
 *
 * generate the actual sound data for this voice
 */
void
xsynth_voice_render(xsynth_synth_t *synth, xsynth_voice_t *voice,
                    LADSPA_Data *out, unsigned long sample_count,
                    int do_control_update)
{
    unsigned long sample;

	synth->monophonic = *synth->monomode;
	synth->glide = *synth->glidemode;

    /* state variables saved in voice */

    float         lfo_pos    = voice->lfo_pos,
                  eg1        = voice->eg1,
                  eg2        = voice->eg2;
    unsigned char eg1_phase  = voice->eg1_phase,
                  eg2_phase  = voice->eg2_phase;
    int           osc_index  = voice->osc_index;

    /* temporary variables used in calculating voice */

    float fund_pitch;
    float deltat = synth->deltat;
    float freq, freqkey, freqeg1, freqeg2, lfo;

    /* set up synthesis variables from patch */
    float         omega1, omega2;
    unsigned char osc_sync = (*(synth->osc_sync) > 0.0001f);
    float         omega3 = *(synth->lfo_frequency);
    unsigned char lfo_waveform = lrintf(*(synth->lfo_waveform));
    float         lfo_amount_o = *(synth->lfo_amount_o);
    float         lfo_amount_f = *(synth->lfo_amount_f);
    float         eg1_amp = qdB_to_amplitude(velocity_to_attenuation[voice->velocity] *
                                             *(synth->eg1_vel_sens));
    float         eg1_rate_level[3], eg1_one_rate[3];
    float         eg1_amount_o = *(synth->eg1_amount_o);
    float         eg2_amp = qdB_to_amplitude(velocity_to_attenuation[voice->velocity] *
                                             *(synth->eg2_vel_sens));
    float         eg2_rate_level[3], eg2_one_rate[3];
    float         eg2_amount_o = *(synth->eg2_amount_o);
    unsigned char vcf_mode = lrintf(*(synth->vcf_mode));
    float         qres = *(synth->vcf_qres) / 1.995f * voice->pressure;  /* now 0 to 1 */
    float         balance1 = 1.0f - *(synth->osc_balance);
    float         balance2 = *(synth->osc_balance);
    float         vol_out = volume(*(synth->volume) * synth->cc_volume);

    fund_pitch = *(synth->glide_time) * voice->target_pitch +
                 (1.0f - *(synth->glide_time)) * voice->prev_pitch;    /* portamento */
    if (do_control_update) {
        voice->prev_pitch = fund_pitch; /* save pitch for next time */
    }

    fund_pitch *= synth->pitch_bend * *(synth->tuning);
    
    omega1 = *(synth->osc1_pitch) * fund_pitch;
    omega2 = *(synth->osc2_pitch) * fund_pitch;

    eg1_rate_level[0] = *(synth->eg1_attack_time) * eg1_amp;  /* eg1_attack_time * 1.0f * eg1_amp */
    eg1_one_rate[0] = 1.0f - *(synth->eg1_attack_time);
    eg1_rate_level[1] = *(synth->eg1_decay_time) * *(synth->eg1_sustain_level) * eg1_amp;
    eg1_one_rate[1] = 1.0f - *(synth->eg1_decay_time);
    eg1_rate_level[2] = 0.0f;                                 /* eg1_release_time * 0.0f * eg1_amp */
    eg1_one_rate[2] = 1.0f - *(synth->eg1_release_time);
    eg2_rate_level[0] = *(synth->eg2_attack_time) * eg2_amp;
    eg2_one_rate[0] = 1.0f - *(synth->eg2_attack_time);
    eg2_rate_level[1] = *(synth->eg2_decay_time) * *(synth->eg2_sustain_level) * eg2_amp;
    eg2_one_rate[1] = 1.0f - *(synth->eg2_decay_time);
    eg2_rate_level[2] = 0.0f;
    eg2_one_rate[2] = 1.0f - *(synth->eg2_release_time);

    eg1_amp *= 0.99f;  /* Xsynth's original eg phase 1 to 2 transition check was:  */
    eg2_amp *= 0.99f;  /*    if (!eg1_phase && eg1 > 0.99f) eg1_phase = 1;         */

    freq = M_PI_F * deltat * fund_pitch * synth->mod_wheel;  /* now (0 to 1) * pi */
    freqkey = freq * *(synth->vcf_cutoff);
    freqeg1 = freq * *(synth->eg1_amount_f);
    freqeg2 = freq * *(synth->eg2_amount_f);

    /* copy some things so oscillator functions can see them */
    voice->osc1.waveform = lrintf(*(synth->osc1_waveform));
    voice->osc1.pw       = *(synth->osc1_pulsewidth);
    voice->osc2.waveform = lrintf(*(synth->osc2_waveform));
    voice->osc2.pw       = *(synth->osc2_pulsewidth);

    /* --- LFO, EG1, and EG2 section */

    for (sample = 0; sample < sample_count; sample++) {

        lfo = oscillator(&lfo_pos, omega3, deltat, lfo_waveform);

        eg1 = eg1_rate_level[eg1_phase] + eg1_one_rate[eg1_phase] * eg1;
        eg2 = eg2_rate_level[eg2_phase] + eg2_one_rate[eg2_phase] * eg2;

        voice->osc2_w_buf[sample] = deltat * omega2 *
                                    (1.0f + eg1 * eg1_amount_o) *
                                    (1.0f + eg2 * eg2_amount_o) *
                                    (1.0f + lfo * lfo_amount_o);

        voice->freqcut_buf[sample] = (freqkey + freqeg1 * eg1 + freqeg2 * eg2) *
                                     (1.0f + lfo * lfo_amount_f);

        voice->vca_buf[sample] = eg1 * vol_out;

        if (!eg1_phase && eg1 > eg1_amp) eg1_phase = 1;  /* flip from attack to decay */
        if (!eg2_phase && eg2 > eg2_amp) eg2_phase = 1;  /* flip from attack to decay */
    }

    /* --- VCO 1 section */

    if (osc_sync)
        blosc_master(sample_count, voice, &voice->osc1,
                     osc_index, balance1, deltat * omega1);
    else
        blosc_single1(sample_count, voice, &voice->osc1,
                      osc_index, balance1, deltat * omega1);

    /* --- VCO 2 section */

    if (osc_sync)
        blosc_slave(sample_count, voice, &voice->osc2,
                     osc_index, balance2, voice->osc2_w_buf);
    else
        blosc_single2(sample_count, voice, &voice->osc2,
                      osc_index, balance2, voice->osc2_w_buf);

    /* --- VCF and VCA section */

    switch (vcf_mode) {
      default:
      case 0:
        vcf_2pole(voice, sample_count, voice->osc_audio + osc_index, out,
                  voice->freqcut_buf, qres, voice->vca_buf);
        break;
      case 1:
        vcf_4pole(voice, sample_count, voice->osc_audio + osc_index, out,
                  voice->freqcut_buf, qres, voice->vca_buf);
        break;
      case 2:
        vcf_mvclpf(voice, sample_count, voice->osc_audio + osc_index, out,
                   voice->freqcut_buf, qres, voice->vca_buf);
        break;
    }

    osc_index += sample_count;

    if (do_control_update) {
        /* do those things should be done only once per control-calculation
         * interval ("nugget"), such as voice check-for-dead, pitch envelope
         * calculations, volume envelope phase transition checks, etc. */

        /* check if we've decayed to nothing, turn off voice if so */
        if (eg1_phase == 2 &&
            voice->vca_buf[sample_count - 1] < 6.26e-6f) {
            /* sound has completed its release phase (>96dB below volume '5' max) */

            XDB_MESSAGE(XDB_NOTE, " xsynth_voice_render check for dead: killing note id %d\n", voice->note_id);
            xsynth_voice_off(voice);
            return; /* we're dead now, so return */
        }

        /* already saved prev_pitch above */

        /* check oscillator audio buffer index, shift buffer if necessary */
        if (osc_index > MINBLEP_BUFFER_LENGTH - (XSYNTH_NUGGET_SIZE + LONGEST_DD_PULSE_LENGTH)) {
            memcpy(voice->osc_audio, voice->osc_audio + osc_index,
                   LONGEST_DD_PULSE_LENGTH * sizeof (float));
            memset(voice->osc_audio + LONGEST_DD_PULSE_LENGTH, 0,
                   (MINBLEP_BUFFER_LENGTH - LONGEST_DD_PULSE_LENGTH) * sizeof (float));
            osc_index = 0;
        }
    }

    /* save things for next time around */

    voice->lfo_pos    = lfo_pos;
    voice->eg1        = eg1;
    voice->eg1_phase  = eg1_phase;
    voice->eg2        = eg2;
    voice->eg2_phase  = eg2_phase;
    voice->osc_index  = osc_index;
}