概要

libflac++とは

flacを扱いやすくするためのC++ライブラリ。

ダウンロード

ここから落としてくる。
ここに書いてるのはver1.3.1

ライセンス

ライブラリ

New BSD ライセンス(修正BSD)

この記事

http://creativecommons.org/licenses/by/4.0/deed.ja

使用方法

基本的にオーバーライドして使う模様
静的ライブラリとして使う場合は

#define FLAC__NO_DLL

をソースに追加。
じゃないと__imp__***が見つからないってめっちゃ起こって気づくのに2日かかる(実話)

デコーダ

class m_Decoder : public FLAC::Decoder::Stream
{
public:
	m_Decoder(FILE *f_) : FLAC::Decoder::Stream(), f(f_) {
		buffer.clear();
	}
	vector<int32_t> buffer;
	uint64_t getTotalSample()		{ return totalSamples; }
	unsigned int getSampleRate()	{ return sampleRate; }
	unsigned int getChannels()		{ return channels; }
	unsigned int getBitPerSeconds()	{ return bps; }
protected:
	FILE *f;

	virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
	virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes);
	virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata);
	virtual void error_callback(::FLAC__StreamDecoderErrorStatus status);


private:
	m_Decoder(const m_Decoder&);
	m_Decoder&operator=(const m_Decoder&);

	FLAC__uint64 totalSamples = 0;
	unsigned int sampleRate = 0;
	unsigned int channels = 0;
	unsigned int bps = 0;
};

関数のオーバーライド

基本的にコールバックが呼ばれる。

write_callback

FLACをデコードしたRAWデータが出てくる場所

::FLAC__StreamDecoderWriteStatus m_Decoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 *const buffer[])
{
	for (unsigned int i = 0; i < frame->header.blocksize; i++)
	{
		for (unsigned int channels = 0; channels < frame->header.channels; channels++)
		{
			this->buffer.push_back(buffer[channels][i]);
		}
	}
	return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}

read_callback

ファイルを読むときに呼び出される場所。 ちゃんと書けばstream系も使える。

::FLAC__StreamDecoderReadStatus m_Decoder::read_callback(FLAC__byte buffer[], size_t *bytes)
{
	const size_t size = *bytes;
	if (feof(f)){
		*bytes = 0;
		return FLAC__StreamDecoderReadStatus::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
	}
	else if (size > 0)
	{
		*bytes = ::fread(buffer, 1, size, f);
		if (*bytes == 0){
			if (feof(f))
				return FLAC__StreamDecoderReadStatus::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
			else
			{
				return FLAC__StreamDecoderReadStatus::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
			}
		}
		else
		{
			return FLAC__StreamDecoderReadStatus::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
		}
	}
	else
		return FLAC__StreamDecoderReadStatus::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
}

metadata_callback

メタデータが出てくる場所。

void m_Decoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
{
	if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
		totalSamples = metadata->data.stream_info.total_samples;
		sampleRate = metadata->data.stream_info.sample_rate;
		channels = metadata->data.stream_info.channels;
		bps = metadata->data.stream_info.bits_per_sample;
	}
}

error_callback

エラーが発生した時に呼ばれる。確かサンプルからコピった。

void m_Decoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
{
	fprintf(stderr, "Got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
}

コード

#include <FLAC++/all.h>
#include <vector>
#include "m_Decoder.h"

using namespace FLAC;
using namespace std;

static FLAC__uint64 total_samples = 0;
static unsigned sample_rate = 0;
static unsigned channels = 0;
static unsigned bps = 0;
int main(void){
	FILE *fread;
	fopen_s(&fread, "data.flac", "rb");
	m_Decoder decode(fread);
	decode.set_md5_checking(true);
	FLAC__StreamDecoderInitStatus initResult = decode.init();
	if (initResult != FLAC__STREAM_DECODER_INIT_STATUS_OK)
	{
		fprintf(stderr, "ERROR : FLAC Init Error.");
		return 0;
	}
	decode.process_until_end_of_metadata();
	
	// Getting metadeta...
	
	int sample = 0;
	vector<int32_t> RAWData;
	while(total_samples > sample){
		decode.process_single();
		for (int i=0; i<decode.buffer.size(); i++){
			RAWData.push_back(decode.buffer[i]);
			sample++;
		}
		decode.buffer.clear();
	}
	return 0;
}

イメージこんな感じ。

process_until_end_of_stream()もあるけど、全部デコードしちゃうから効果音とか短いのならいいけど長いのは時間かかる。

実際に実行してないから動くかわからない

トップへ


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-11-09 (月) 00:24:52 (2951d)