[LINUX] Benutze Rust, um Pocket Miku zu bewegen.

Ah, ich bin es leid, die Linux-Kernel-Dokumentation zu lesen, also kamen die Spielsachen heraus und ich spielte.

Endlich: Ich habe versucht, Pocket Miku mit Rust zu bewegen

»Es ist gut, dass sich die Dinge bewegen. --low level / raw level Wichtig für das Debuggen.

Referenzmaterial

Wir haben anhand des Inhalts der folgenden Website geprüft. Ich habe meine Stimme jedoch noch nicht geändert, daher würde ich gerne etwas mehr darüber nachdenken ...

Was wollten Sie machen

Verwenden wir RUST, um das "Pocket Miku" zu bewegen, das nach dem Aufräumen herauskam.

Überprüfen Sie die von alsa erkannte ID usw.

Als ich mit dem Konto-Befehl nachgesehen habe, war es NSX-39, also scheint "20: 0" in Ordnung zu sein.

[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]$

Integrieren Sie eine Bibliothek zur Manipulation von Midi mit Rost (ALSA)

Alsa hinzugefügt und zu Cargo.toml geklatscht.

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"

Machen Sie einen Sound von Pocket Miku über alsa

Rost alsa Wrapper Dies ist weder in einer Hand noch in dieser. Vorerst bestätigte ich, dass es ein Geräusch gab.

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();
}

Es war Strace, die beim Debuggen half

Zuerst fragte ich mich, warum es keinen Ton gab. Zu diesem Zeitpunkt war es strace, das für das Debuggen nützlich war.

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? Ich kann mit nichts umgehen. damit,

note (& miku, alsa :: seq :: EventType :: Note, 0, 60, 64, client_port); Sie haben festgestellt, dass 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)

Schließlich ist das Debuggen auf Raw-Level / Low-Level wichtig! !!

TODO

Ich möchte Sysex verwenden, um zu ändern, was ich sage ...

Das ist es.

Recommended Posts

Benutze Rust, um Pocket Miku zu bewegen.
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Wie benutzt man Seaboan?
Verwendung von Image-Match
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Einfach zu bedienende Flasche
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Gründe für die Verwendung von log
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Einfach zu bedienendes SQLite3
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Python-How zur Verwendung von Pyinstaller
Verwendung von OptParse
Verwendung von return
Wie man Imutils benutzt
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verstehen Sie, wie man Django-Filter verwendet
Verwenden Sie MeCab, um Messwerte abzurufen
Verwendung des Generators
[Python] Verwendung von Liste 1
QSM-Analyse - Verwendung von MEDI-
Verwendung von FastAPI ③ OpenAPI
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
[Go] Verwendung von "... (3 Perioden)"
So bedienen Sie GeoIp2 von Django
Einfach zu bedienendes E-Cell 4 Intermediate
[Python] Verwendung von input ()
Wie benutzt man den Dekorateur?
[Einführung] Verwendung von open3d