Ah, j'en ai assez de lire la documentation du noyau Linux, alors les jouets sont sortis et j'ai joué.
«C'est bien que les choses bougent. --low level / raw level Important pour le débogage.
Nous avons examiné sur la base du contenu du site suivant. Cependant, je n'ai pas encore changé de voix, alors j'aimerais y réfléchir un peu plus ...
Utilisons RUST pour déplacer le "Pocket Miku" qui est sorti après le nettoyage.
Quand j'ai vérifié en utilisant la commande de compte, c'était NSX-39, donc "20: 0" semble être bien.
[kmtr@localhost rust-alsa]$ sudo LANG=C aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 16: 'Ensoniq AudioPCI' [type=kernel,card=0]
    0 'ES1371          '
client 20: 'NSX-39' [type=kernel,card=1]
    0 'NSX-39 MIDI 1   '
[kmtr@localhost rust-alsa]$
Ajouté alsa et clap à Cargo.toml.
Cargo.toml
[package]
name = "rust-alsa"
version = "0.1.0"
authors = ["kmtr"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
alsa = "0.4.2"
clap = "2.20"
emballage alsa de rust Ce n'est ni dans une main ni dans celle-ci. Pour le moment, j'ai confirmé qu'il y avait un son.
src/main.rs
extern crate alsa;
use std::error;
use alsa::seq;
use std::ffi::CString;
use std::thread::sleep;
use std::time::Duration;
const DEFAULT_NAME: &str = "RUSTMIKU";
const MIKU_ID:   i32 = 20;
const MIKU_PORT: i32 = 0;
fn note( s: &alsa::Seq, evt : alsa::seq::EventType,  channel : u8, note: u8, velocity : u8, s_port:i32)
{
        let o_note = alsa::seq::EvNote {
                channel,
                note,
                velocity,
                off_velocity: 0,
                duration: 0
        };
        let mut o_event = alsa::seq::Event::new( evt , &o_note );
        o_event.set_direct();
        o_event.set_source( s_port );
        o_event.set_dest( alsa::seq::Addr { client: MIKU_ID, port: MIKU_PORT } );
        s.event_output( &mut o_event ) ;
        s.drain_output();
}
fn sing() -> Result<alsa::Seq,  Box<dyn error::Error> > {
        // snd_seq_open()
        let miku = alsa::Seq::open( None, Some(alsa::Direction::Playback), false ) ?;
        // snd_seq_create_simple_port()
        let cstr = CString::new(DEFAULT_NAME)?;
        let client_port = miku.create_simple_port(&cstr,
                alsa::seq::PortCap::READ,
                alsa::seq::PortType::MIDI_GENERIC | alsa::seq::PortType::APPLICATION )?;
        // subscribe_port()
        let client_id = miku.client_id()?;
        let subs = seq::PortSubscribe::empty()?;
        subs.set_dest  (seq::Addr { client: MIKU_ID,   port: MIKU_PORT } );
        subs.set_sender(seq::Addr { client: client_id, port: client_port });
        miku.subscribe_port(&subs)?;
        // Note on
        note ( &miku, alsa::seq::EventType::Noteon,  0, 60, 64, client_port );
        // Wait
        sleep ( Duration::from_millis(1000) );
        // Note off
        note ( &miku, alsa::seq::EventType::Noteoff, 0, 60, 64, client_port );
        Ok(miku)
}
fn main() {
        sing();
}
Au début, je me demandais pourquoi il n'y avait pas de son. A cette époque, c'était strace qui était utile pour le débogage.
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
ioctl(3, SNDRV_SEQ_IOCTL_PVERSION, 0x7ffe4a9ffeb8) = 0
ioctl(3, SNDRV_SEQ_IOCTL_CLIENT_ID, 0x7ffe4a9ffebc) = 0
ioctl(3, SNDRV_SEQ_IOCTL_RUNNING_MODE, 0x7ffe4a9ffec0) = 0
ioctl(3, SNDRV_SEQ_IOCTL_CREATE_PORT, 0x7ffe4aa00260) = 0
ioctl(3, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, 0x560006f2b5b0) = 0
write(3, "\5\0\0\375\0\0\0\0\0\0\0\0\0\0\24\0\0<@\0\0\0\0\0\0\0\0\0", 28) = -1 EINVAL (Invalid argument)
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffe4aa00340) = 0
write(3, "\5\0\0\375\0\0\0\0\0\0\0\0\0\0\24\0\0<@\0\0\0\0\0\0\0\0\0\7\0\0\375"..., 56) = -1 EINVAL (Invalid argument)
close(3)                                = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7f57fe537000, 8192)            = 0
exit_group(0)                           = ?
+++ exited with 0 +++
Hmm? Je ne peux rien gérer. alors,
note (& miku, alsa :: seq :: EventType :: Note, 0, 60, 64, client_port);  Vous avez remarqué que note (& miku, alsa :: seq :: EventType :: Noteon, 0, 60, 64, client_port);`.
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
ioctl(3, SNDRV_SEQ_IOCTL_PVERSION, 0x7ffc72b00148) = 0
ioctl(3, SNDRV_SEQ_IOCTL_CLIENT_ID, 0x7ffc72b0014c) = 0
ioctl(3, SNDRV_SEQ_IOCTL_RUNNING_MODE, 0x7ffc72b00150) = 0
ioctl(3, SNDRV_SEQ_IOCTL_CREATE_PORT, 0x7ffc72b004f0) = 0
ioctl(3, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, 0x556f313ee5b0) = 0
write(3, "\6\0\0\375\0\0\0\0\0\0\0\0\0\0\24\0\0<@\0\0\0\0\0\0\0\0\0", 28) = 28
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffc72b005d0) = 0
write(3, "\7\0\0\375\0\0\0\0\0\0\0\0\0\0\24\0\0<@\0\0\0\0\0\0\0\0\0", 28) = 28
close(3)                                = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7f59d2ff5000, 8192)            = 0
exit_group(0)
Après tout, le débogage au niveau brut / bas niveau est important! !!
TODO
Je veux utiliser sysex pour changer ce que je dis ...
C'est tout.
Recommended Posts