1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rustを使ってポケットミクに「みくみくにしてやんよー」と言わせた(完結編)

Last updated at Posted at 2020-05-05

なんというか、音を出せたからそれで満足って、するわけないじゃないですか!!

ここはもう、「みくみくにしてやんよー」まで言わせましょう!!

要約:Rustでは、コンパイル時のエラーメッセージはしっかり見よう

  • Rustの場合、問題解決策がエラーメッセージにでていることもある。
  • 試行錯誤も重要だけど、ここらへんは経験が必要だなあ、、、と。

参考文献

基本的には、こちらのQiita投稿されたものを、Rustへ移植?(と呼べるのか… 申し訳ないです)となります。

ポケット・ミクを MIDI 操作で歌わせてみた

rawmidiの制御に関しては、下記も参考にしています。

どうすれば、ポケットミクを制御できるのか?

ALSAには、rawmidi interfaceがあるので、これを使えば直接やり取りできそう。というところまでは、昨日5/4には見つけていた。

Rust Alsa にもあるし、これは楽勝なのでは?(と、このときはそう思っていました)

完成品

とりあえず試行錯誤のものを出してから、何で苦しんだかをまとめておく。

main.rs
extern crate alsa;

use std::error;
use std::ffi::CString;
use std::thread::sleep;
use std::time::Duration;
use std::io::Write;

fn sing() -> Result<alsa::rawmidi::Rawmidi,  Box<dyn error::Error> > {
        let cstr = CString::new("hw:1")?;
        let miku = alsa::rawmidi::Rawmidi::open( &cstr, alsa::Direction::Playback, false ) ?;

        let mut init_lyric: [u8; 18]  =
        [
                0xF0u8, 0x43u8, 0x79u8, 0x09u8, 0x11u8,
                0x0Au8,
                0x01u8,
                        101u8,  // み
                        7u8,    // く
                        101u8,  // み
                        7u8,    // く
                        64u8,   // に
                        32u8,   // し
                        44u8,   // て
                        108u8,  // や
                        125u8,  // ん
                        110u8,  // よ
                0xF7u8,
        ];

        let mut next_lyric: [u8; 19]  =
        [
                0xF0u8, 0x43u8, 0x79u8, 0x09u8, 0x11u8,
                0x0Du8, // Direct Command
                        0x09u8, 0x05u8, 0x00u8, 0x00u8,
                        0x08u8, 0x01u8, 0x00u8, 0x00u8,
                        0x09u8, 0x01u8, 0x00u8, 0x00u8,
                0xF7u8,
        ];

        let mut buf_note_on: [u8;11]  =
        [
                0xF0u8, 0x43u8, 0x79u8, 0x09u8, 0x11u8,
                0x0Du8,
                        0x08u8,
                        0x09u8,
                        0x29u8,
                        0x00u8,
                0xF7u8,
        ];
        let mut buf_note_off: [u8;11]  =
        [
                0xF0u8, 0x43u8, 0x79u8, 0x09u8, 0x11u8,
                0x0Du8,
                        0x08u8,
                        0x08u8,
                        0x00u8,
                        0x00u8,
                0xF7u8,
        ];

        let durations : [ u64; 11 ] = [
                100,
                300,
                100,
                300,
                200,
                300,
                300,
                100,
                300,
                300,
                300,
        ];

        miku.io().write(&mut init_lyric )?;
        // note off
        miku.io().write(&mut buf_note_off );

        for duration in &durations {
                // note on
                miku.io().write(&mut buf_note_on );
                // Wait
                sleep ( Duration::from_millis( *duration ) );
                // note off
                miku.io().write(&mut buf_note_off );
                // goto next
                miku.io().write(&mut next_lyric )?;
        }

        Ok(miku)
}

fn main() {
        sing();
}

初期化方法は大体わかった

初期化してインスタンス作るところまでは、そんなに苦労せずにできた。

let cstr = CString::new("hw:1")?;
        let miku = alsa::rawmidi::Rawmidi::open( &cstr, alsa::Direction::Playback, false ) ?;

データを書き込み方が分からない、どうなってんだろう?

NG

 miku.write( &mut init_lyric );
 miku.Write( &mut init_lyric );
 miku.IO().write( &mut init_lyric );
 miku.IO().Write( &mut init_lyric );

などでもだめだめでどうすればいいんだー、と
rust-alsaのドキュメントやソースコードをいったりきたり。

で、ふとエラーを確認したところ・・・あれ?直し方も書いてる?

コンパイル時のエラー

[kmtr@localhost rust-alsa-raw]$ cargo build
   Compiling rust-alsa v0.1.0 (/home/kmtr/work/rust-alsa-raw)
error[E0599]: no method named `write` found for struct `alsa::rawmidi::IO<'_>` in the current scope
  --> src/main.rs:76:12
   |
76 |     miku.io().write(&mut init_lyric )?;
   |               ^^^^^ method not found in `alsa::rawmidi::IO<'_>`
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
   |
3  | use std::io::Write;
   |

ということで、下記行を追加したところ無事にコンパイルが通りました、と。

use std::io::Write;

以上になります。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?