Пример #1
0
OSStatus	MusicDeviceBase::HandleNoteOff(	UInt8 	inChannel,
											UInt8 	inNoteNumber,
											UInt8 	inVelocity,
											UInt32 	inStartFrame)
{
	return StopNote (inChannel, inNoteNumber, inStartFrame);
}
Пример #2
0
MMRESULT
ProcessShortMidiMessage(
    DeviceInfo* device_info,
    DWORD message)
{
    DWORD status;

    DWORD category;
    DWORD channel;
    DWORD data1, data2;

    status = message & 0x000000FF;

    /* Deal with running status */

    if ( status < MIDI_NOTE_OFF )
    {
        status = device_info->running_status;
    }

    /* Ensure the status is sane! */

    if ( status < MIDI_NOTE_OFF )
    {
        /* It's garbage, ignore it */
        return MMSYSERR_NOERROR;
    }

    /* Figure out the message category and channel */

    category = status & 0xF0;
    channel = status & 0x0F;    /* we don't use this */

    data1 = (message & 0x0000FF00) >> 8;
    data2 = (message & 0x00FF0000) >> 16;

    DPRINT("0x%x, %d, %d\n", (int) status, (int) data1, (int) data2);

    /* Filter drums (which are *usually* on channel 10) */
    if ( channel == 10 )
    {
        return MMSYSERR_NOERROR;
    }

    /* Pass to the appropriate message handler */

    switch ( category )
    {
        case MIDI_NOTE_ON :
        {
            PlayNote(device_info, data1, data2);
            break;
        }

        case MIDI_NOTE_OFF :
        {
            StopNote(device_info, data1);
            break;
        }
    }

    return MMSYSERR_NOERROR;
}
Пример #3
0
    //--------------------------------------------------------------------------------------------------
    void OnKey (char key, bool pressed) {

        // pressing numbers switches instruments
        if (pressed) {
            switch (key)
            {
                case '1': g_currentWaveForm = e_waveSine; ReportParams(); return;
                case '2': g_currentWaveForm = e_waveSaw; ReportParams(); return;
                case '3': g_currentWaveForm = e_waveSquare; ReportParams(); return;
                case '4': g_currentWaveForm = e_waveTriangle; ReportParams(); return;
                case '5': g_currentDelay = e_delayNone; ReportParams(); return;
                case '6': g_currentDelay = e_delay1; ReportParams(); return;
                case '7': g_currentDelay = e_delay2; ReportParams(); return;
                case '8': g_currentDelay = e_delay3; ReportParams(); return;
                case '9': {
                    std::lock_guard<std::mutex> guard(g_notesMutex);
                    g_notes.push_back(SNote(0.0f, e_sampleCymbals));
                    return;
                }
                case '0': {
                    std::lock_guard<std::mutex> guard(g_notesMutex);
                    g_notes.push_back(SNote(0.0f, e_sampleVoice));
                    return;
                }
            }
        }

        // figure out what frequency to play
        float frequency = 0.0f;
        switch (key) {

            // QWERTY row
            case 'Q': frequency = NoteToFrequency(3, 0); break;
            case 'W': frequency = NoteToFrequency(3, 1); break;
            case 'E': frequency = NoteToFrequency(3, 2); break;
            case 'R': frequency = NoteToFrequency(3, 3); break;
            case 'T': frequency = NoteToFrequency(3, 4); break;
            case 'Y': frequency = NoteToFrequency(3, 5); break;
            case 'U': frequency = NoteToFrequency(3, 6); break;
            case 'I': frequency = NoteToFrequency(3, 7); break;
            case 'O': frequency = NoteToFrequency(3, 8); break;
            case 'P': frequency = NoteToFrequency(3, 9); break;
            case -37: frequency = NoteToFrequency(3, 10); break;

            // ASDF row
            case 'A': frequency = NoteToFrequency(2, 0); break;
            case 'S': frequency = NoteToFrequency(2, 1); break;
            case 'D': frequency = NoteToFrequency(2, 2); break;
            case 'F': frequency = NoteToFrequency(2, 3); break;
            case 'G': frequency = NoteToFrequency(2, 4); break;
            case 'H': frequency = NoteToFrequency(2, 5); break;
            case 'J': frequency = NoteToFrequency(2, 6); break;
            case 'K': frequency = NoteToFrequency(2, 7); break;
            case 'L': frequency = NoteToFrequency(2, 8); break;
            case -70: frequency = NoteToFrequency(2, 9); break;
            case -34: frequency = NoteToFrequency(2, 10); break;

            // ZXCV row
            case 'Z': frequency = NoteToFrequency(1, 0); break;
            case 'X': frequency = NoteToFrequency(1, 1); break;
            case 'C': frequency = NoteToFrequency(1, 2); break;
            case 'V': frequency = NoteToFrequency(1, 3); break;
            case 'B': frequency = NoteToFrequency(1, 4); break;
            case 'N': frequency = NoteToFrequency(1, 5); break;
            case 'M': frequency = NoteToFrequency(1, 6); break;
            case -68: frequency = NoteToFrequency(1, 7); break;
            case -66: frequency = NoteToFrequency(1, 8); break;
            case -65: frequency = NoteToFrequency(1, 9); break;
            case -95: frequency = NoteToFrequency(1, 10); break;  // right shift

            // left shift = low freq
            case 16: frequency = NoteToFrequency(0, 5); break;

            // left shift = low freq
            case -94: frequency = NoteToFrequency(0, 0); break;

            default: {
                return;
            }
        }

        // if releasing a note, we need to find and kill the flute note of the same frequency
        if (!pressed) {
            StopNote(frequency);
            return;
        }

        // get a lock on our notes vector and add the new note
        std::lock_guard<std::mutex> guard(g_notesMutex);
        g_notes.push_back(SNote(frequency, g_currentWaveForm));
    }
Пример #4
0
MMRESULT
PlayNote(
    DeviceInfo* device_info,
    UCHAR note,
    UCHAR velocity)
{
    HANDLE heap = GetProcessHeap();

    NoteNode* node;

    DPRINT("PlayNote\n");

    if ( velocity == 0 )
    {
        DPRINT("Zero velocity\n");

        /* Velocity zero is effectively a "note off" */
        StopNote(device_info, note);
    }
    else
    {
        /* Start playing the note */
        NoteNode* new_node;

        EnterCriticalSection(&device_lock);

        node = device_info->note_list;

        while ( node != NULL )
        {
#ifndef ALLOW_DUPLICATE_NOTES
            if ( ( node->note == note ) && ( velocity > 0 ) )
            {
                /* The note is already playing - do nothing */
                DPRINT("Duplicate note playback request ignored\n");
                LeaveCriticalSection(&device_lock);
                return MMSYSERR_NOERROR;
            }
#endif

            node = node->next;
        }

        new_node = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(NoteNode));

        if ( ! new_node )
        {
            LeaveCriticalSection(&device_lock);
            return MMSYSERR_NOMEM;
        }

        new_node->note = note;
        new_node->velocity = velocity;

        /*
            Prepend to the playing notes list. If exceeding polyphony,
            remove the oldest note (which will be at the tail.)
        */

        if ( device_info->note_list )
            device_info->note_list->previous = new_node;

        new_node->next = device_info->note_list;
        new_node->previous = NULL;

        device_info->note_list = new_node;
        device_info->playing_notes_count ++;

/*
        if ( device_info->playing_notes_count > POLYPHONY )
        {
            ASSERT(tail_node);

            DPRINT("Polyphony exceeded\n");

            tail_node->previous->next = NULL;

            HeapFree(heap, 0, tail_node);

            device_info->playing_notes_count --;
        }
*/

        LeaveCriticalSection(&device_lock);

        DPRINT("Note started - now playing %d notes\n", (int) device_info->playing_notes_count);
        device_info->refresh_notes = TRUE;
    }

#ifndef CONTINUOUS_NOTES
    ProcessPlayingNotes((PVOID) device_info);
#endif

    return MMSYSERR_NOERROR;
}