Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  handler.rs

  Sprache: Rust
 

use std::io::{stderr, Write};
use std::{mem, slice};

use windows::Win32::Media::Audio::{midiInAddBuffer, HMIDIIN, MIDIHDR};
use windows::Win32::Media::{MMSYSERR_NOERROR, MM_MIM_DATA, MM_MIM_LONGDATA, MM_MIM_LONGERROR};

use crate::Ignore;

use super::{DWORD, DWORD_PTR, UINT};

use super::HandlerData;

pub extern "system" fn handle_input<T>(
    _: HMIDIIN,
    input_status: UINT,
    instance_ptr: DWORD_PTR,
    midi_message: DWORD_PTR,
    timestamp: DWORD,
) {
    if input_status != MM_MIM_DATA
        && input_status != MM_MIM_LONGDATA
        && input_status != MM_MIM_LONGERROR
    {
        return;
    }

    let data: &mut HandlerData<T> = unsafe { &mut *(instance_ptr as *mut HandlerData<T>) };

    // Calculate time stamp.
    data.message.timestamp = timestamp as u64 * 1000// milliseconds -> microseconds

    if input_status == MM_MIM_DATA {
        // Channel or system message
        // Make sure the first byte is a status byte.
        let status: u8 = (midi_message & 0x000000FF) as u8;
        if status & 0x80 == 0 {
            return;
        }

        // Determine the number of bytes in the MIDI message.
        let nbytes: u16 = if status < 0xC0 {
            3
        } else if status < 0xE0 {
            2
        } else if status < 0xF0 {
            3
        } else if status == 0xF1 {
            if data.ignore_flags.contains(Ignore::Time) {
                return;
            } else {
                2
            }
        } else if status == 0xF2 {
            3
        } else if status == 0xF3 {
            2
        } else if status == 0xF8 && (data.ignore_flags.contains(Ignore::Time)) {
            // A MIDI timing tick message and we're ignoring it.
            return;
        } else if status == 0xFE && (data.ignore_flags.contains(Ignore::ActiveSense)) {
            // A MIDI active sensing message and we're ignoring it.
            return;
        } else {
            1
        };

        // Copy bytes to our MIDI message.
        let ptr = (&midi_message) as *const DWORD_PTR as *const u8;
        let bytes: &[u8] = unsafe { slice::from_raw_parts(ptr, nbytes as usize) };
        data.message.bytes.extend_from_slice(bytes);
    } else {
        // Sysex message (MIM_LONGDATA or MIM_LONGERROR)
        let sysex = unsafe { &*(midi_message as *const MIDIHDR) };
        if !data.ignore_flags.contains(Ignore::Sysex) && input_status != MM_MIM_LONGERROR {
            // Sysex message and we're not ignoring it
            let bytes: &[u8] =
                unsafe { slice::from_raw_parts(sysex.lpData.0, sysex.dwBytesRecorded as usize) };
            data.message.bytes.extend_from_slice(bytes);
            // TODO: If sysex messages are longer than MIDIR_SYSEX_BUFFER_SIZE, they
            //       are split in chunks. We could reassemble a single message.
        }

        // The WinMM API requires that the sysex buffer be requeued after
        // input of each sysex message.  Even if we are ignoring sysex
        // messages, we still need to requeue the buffer in case the user
        // decides to not ignore sysex messages in the future.  However,
        // it seems that WinMM calls this function with an empty sysex
        // buffer when an application closes and in this case, we should
        // avoid requeueing it, else the computer suddenly reboots after
        // one or two minutes.
        if (unsafe { *data.sysex_buffer.0[sysex.dwUser] }).dwBytesRecorded > 0 {
            //if ( sysex->dwBytesRecorded > 0 ) {
            let in_handle = data.in_handle.as_ref().unwrap().0.lock();
            let result = unsafe {
                midiInAddBuffer(
                    *in_handle,
                    data.sysex_buffer.0[sysex.dwUser],
                    mem::size_of::<MIDIHDR>() as u32,
                )
            };
            drop(in_handle);
            if result != MMSYSERR_NOERROR {
                let _ = writeln!(
                    stderr(),
                    "\nError in handle_input: Requeuing WinMM input sysex buffer failed.\n"
                );
            }

            if data.ignore_flags.contains(Ignore::Sysex) {
                return;
            }
        } else {
            return;
        }
    }

    (data.callback)(
        data.message.timestamp,
        &data.message.bytes,
        data.user_data.as_mut().unwrap(),
    );

    // Clear the vector for the next input message.
    data.message.bytes.clear();
}

Messung V0.5 in Prozent
C=83 H=85 G=83

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002