raspberry pi 1でtensrorflow lite その17

#概要

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が、ブロッキングなので、そこを利用した。

以上。