LoginSignup
1
1

More than 5 years have passed since last update.

raspberry pi 1でtensrorflow lite その17

Posted at

概要

raspberry pi 1でtensorflow liteやってみた。
マイク入力を扱うので、alsaを叩いてみた。
そのまま、出力するモデルを学習してみた。
ラズパイで、リアルタイム処理してみた。その2。

Makefileを書く。

CXXFLAGS ?= -I../tensorflow -I../tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/include
LDFLAGS ?= -L../tensorflow/tensorflow/lite/tools/make/gen/rpi_armv6l/lib

.PHONY: all clean

all: main

main: main.cpp
    g++ --std=c++11 main.cpp -O2 $(CXXFLAGS) $(LDFLAGS) -ltensorflow-lite -lstdc++ -lpthread -ldl -lm -lasound -o test

clean:
    rm -f test

Makeして、実行。

#include <vector>
#include <chrono>
#include <iostream>
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include <stdlib.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
using namespace std;

#define OUT_FREQ            44100
#define IN_FREQ             44100
bool is_error(TfLiteStatus const & status)
{
    return status != kTfLiteOk;
}
int main(int argc, char const * argv[])
{
    int err;
    int i,
        j,
        k;
    snd_pcm_t * in_handle;
    snd_pcm_t * out_handle;
    snd_pcm_sframes_t frames1,
        frames2;
    short in_buffer[IN_FREQ * 5];
    short out_buffer[OUT_FREQ * 5];
    if ((err = snd_pcm_open(&in_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0)
    {
        fprintf (stderr, "Capture open error: %s\n", snd_strerror(err));
        return 1;
    }
    if ((err = snd_pcm_set_params(in_handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, IN_FREQ, 1, 1000 * 1000)) < 0)
    {
        fprintf (stderr, "Capture open error: %s\n", snd_strerror(err));
        return 1;
    }
    if ((err = snd_pcm_open(&out_handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
    {
        fprintf (stderr, "Playback open error: %s\n", snd_strerror(err));
        return 1;
    }
    if ((err = snd_pcm_set_params(out_handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, OUT_FREQ, 1, 1500 * 1000)) < 0)
    {
        fprintf (stderr, "Playback open error: %s\n", snd_strerror(err));
        return 1;
    }   
    std::string a = "voice1.tflite";
    TfLiteStatus status;
    std::unique_ptr<tflite::FlatBufferModel> model;
    std::unique_ptr<tflite::Interpreter> interpreter;
    model = tflite::FlatBufferModel::BuildFromFile(a.c_str());
    if (!model)
    {
        std::cerr << "0: Failed to load the model." << std::endl;
        return -1;
    }
    tflite::ops::builtin::BuiltinOpResolver resolver;
    tflite::InterpreterBuilder(* model, resolver)(& interpreter);
    status = interpreter->AllocateTensors();
    if (is_error(status))
    {
        std::cerr << "2: Failed to allocate the memory for tensors." << std::endl;
        return -1;
    }
    float * in = interpreter->typed_input_tensor<float>(0);
    float * out = interpreter->typed_output_tensor<float>(0);
    while(1)
    {
        std::cout << ">";
        frames1 = snd_pcm_readi(in_handle, in_buffer, 44100);
        if (frames1 < 0)
        {
            std::cout << " ?";
            frames1 = snd_pcm_recover(in_handle, frames1, 0);
        }
        std::cout << " >";
        for (i = 0; i < frames1; i += 1000)
        {
            std::cout << ">";
            for (j = 0; j < 1000; j++)
            {
                k = i + j;
                in[0] = in_buffer[k] / 32768.;
                if (i == 0) in[1] = 0;
                else in[1] = (in_buffer[k] - in_buffer[k - 1]) / 32768.;
                status = interpreter->Invoke();
                if (is_error(status))
                    {
                    std::cerr << "3: Failed to invoke the interpreter." << std::endl;
                    return -1;
                    }
                out_buffer[2 * j] = out[0] * 32768.;
                out_buffer[2 * j + 1] = out[0] * 32768.;
            }
            frames2 = snd_pcm_writei(out_handle, out_buffer, 1000);
            if (frames2 < 0)
            {
                frames2 = snd_pcm_recover(out_handle, frames2, 0);
            }
        }
        std::cout << " >" << std::endl;
    }
    snd_pcm_close(in_handle);
    snd_pcm_close(out_handle);
    return 0;
}


結果

エラー吐くが、なんとか実用。
snd_pcm_writeiが、ブロッキングなので、そこを利用した。

以上。

1
1
0

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
1