Пример #1
0
MMRESULT
StopNote(
    DeviceInfo* device_info,
    UCHAR note)
{
    HANDLE heap = GetProcessHeap();
    NoteNode* node;
    NoteNode* prev_node = NULL;

    DPRINT("StopNote\n");

    EnterCriticalSection(&device_lock);

    node = device_info->note_list;

    while ( node != NULL )
    {
        if ( node->note == note )
        {
            /* Found the note - just remove the node from the list */

            DPRINT("Stopping note %d\n", (int) node->note);

            if ( prev_node != NULL )
                prev_node->next = node->next;
            else
                device_info->note_list = node->next;

            HeapFree(heap, 0, node);

            device_info->playing_notes_count --;

            DPRINT("Note stopped - now playing %d notes\n", (int) device_info->playing_notes_count);

#ifdef CONTINUOUS_NOTES
            if (device_info->playing_notes_count == 0)
                ResetEvent(device_info->work_available);
#endif

            LeaveCriticalSection(&device_lock);
            device_info->refresh_notes = TRUE;

            return MMSYSERR_NOERROR;
        }

        prev_node = node;
        node = node->next;
    }

    LeaveCriticalSection(&device_lock);

    /* Hmm, a good idea? */
#ifndef CONTINUOUS_NOTES
    ProcessPlayingNotes((PVOID) device_info);
#endif

    return MMSYSERR_NOERROR;
}
Пример #2
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;
}