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

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

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

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

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

# 参考文献

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

[ポケット・ミクを MIDI 操作で歌わせてみた](https://qiita.com/YuichiSato/items/1c99c6560c285b86ade8)

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

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

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

https://www.alsa-project.org/alsa-doc/alsa-lib/rawmidi.html

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

https://docs.rs/alsa/0.4.2/alsa/rawmidi/struct.Rawmidi.html

# 完成品

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

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

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

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

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

```

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

```rust: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のドキュメントやソースコードをいったりきたり。

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

```bash:コンパイル時のエラー

[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;
```


以上になります。