# 화면 녹화 #5 - AudioCapture 구현

#pragma once

#include <ryulib/base.hpp>
#include <ryulib/debug_tools.hpp>
#include <ryulib/AudioIO.hpp>
#include <ryulib/ThreadQueue.hpp>

const int CHANNELS = 1;
const int SAMPLE_RATE = 44100;
const int SAMPLE_SIZE = 4;
const int FRAMES_PER_BUFFER = 4410;

class AudioCapture {
public:
	AudioCapture()
		: audio_input_(CHANNELS, SAMPLE_RATE, SAMPLE_SIZE, FRAMES_PER_BUFFER)
	{
		// PortAudio 라이브러리 초기화
		Audio::init();

		// 오디오 입력 중 에러가 났을 때 발생하는 이벤트를 처리할 이벤트 핸들러
		audio_input_.setOnError([&](const void* obj, int error_code) {
			DebugOutput::trace("AudioCapture - error_code: %d", error_code);
		});

		// 오디오가 캡쳐될 때 발생하는 이벤트를 처리할 핸들러
		// obj: 이벤트를 발생시킨 객체
		// buffer: 캡쳐된 오디오 데이터의 포인터
		// buffer_size: 캡쳐된 오디오 데이터의 크기
		audio_input_.setOnData([&](const void* obj, const void* buffer, int buffer_size) {
			audio_size_ = buffer_size;
			void* data = malloc(buffer_size);
			memcpy(data, buffer, buffer_size);
			queue_.push(data);
			//DebugOutput::trace("AudioCapture - queue_.size(): %d", queue_.size());
		});
	}

	void start()
	{
		audio_input_.open();
	}

	void stop()
	{
		audio_input_.close();
	}

	void* getAudioData()
	{
		void* data = queue_.pop();
		if (data == NULL) return nullptr;
		return data;
	}

	int getAduioDataSize() {
		return audio_size_;
	}

private:
	int audio_size_ = 0;

	// 오디오 장치에서 오디오를 캡쳐
	AudioInput audio_input_;

	// 스레드 세이프한 큐
	ThreadQueue<void*> queue_;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68