File: sampleRendering.cpp

package info (click to toggle)
giada 1.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,516 kB
  • sloc: cpp: 30,620; sh: 144; xml: 66; makefile: 55; ansic: 1
file content (102 lines) | stat: -rw-r--r-- 3,004 bytes parent folder | download
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "../src/core/rendering/sampleRendering.h"
#include "../src/core/channels/channel.h"
#include <catch2/catch_test_macros.hpp>

TEST_CASE("rendering::sampleRendering")
{
	using namespace giada;

	constexpr int BUFFER_SIZE  = 1024;
	constexpr int NUM_CHANNELS = 2;

	// Wave values: [1..BUFFERSIZE*4]
	m::Wave wave(0);
	wave.getBuffer().alloc(BUFFER_SIZE * 4, NUM_CHANNELS);
	wave.getBuffer().forEachFrame([](float* f, int i)
	{
		f[0] = static_cast<float>(i + 1);
		f[1] = static_cast<float>(i + 1);
	});

	m::ChannelShared channelShared(0, BUFFER_SIZE);
	m::Channel       channel(ChannelType::SAMPLE, 1, channelShared);

	channelShared.quantizer.emplace();
	channelShared.renderQueue.emplace(/*size=*/16);
	channelShared.resampler.emplace(Resampler::Quality::LINEAR, G_MAX_IO_CHANS);

	SECTION("Test initialization")
	{
		REQUIRE(channel.sampleChannel->hasWave(0) == false);
	}

	SECTION("Test rendering")
	{
		channel.loadSample({&wave, {}}, /*scene=*/0);

		REQUIRE(channel.sampleChannel->hasWave(0) == true);
		REQUIRE(channel.sampleChannel->getRange(0).a == 0);
		REQUIRE(channel.sampleChannel->getRange(0).b == wave.getBuffer().countFrames());

		REQUIRE(channelShared.tracker.load() == 0);
		REQUIRE(channelShared.playStatus.load() == ChannelStatus::OFF);

		for (const float pitch : {1.0f, 0.5f})
		{
			channel.sampleChannel->setPitch(pitch, /*scene=*/0);

			SECTION("Sub-range [M, N), pitch == " + std::to_string(pitch))
			{
				constexpr int RANGE_BEGIN = 16;
				constexpr int RANGE_END   = 48;

				channel.sampleChannel->setRange({RANGE_BEGIN, RANGE_END}, /*scene=*/0);

				channelShared.renderQueue->enqueue({m::rendering::RenderInfo::Mode::NORMAL, 0});

				m::rendering::renderSampleChannel(channel, /*scene=*/0, /*seqIsRunning=*/false);

				int numFramesWritten = 0;
				channelShared.audioBuffer.forEachFrame([&numFramesWritten](float* f, int)
				{
					if (f[0] != 0.0)
						numFramesWritten++;
				});

				REQUIRE(numFramesWritten == (RANGE_END - RANGE_BEGIN) / pitch);
			}

			SECTION("Rewind, pitch == " + std::to_string(pitch))
			{
				// Point in audio buffer where the rewind takes place
				const int OFFSET = 256;

				channelShared.renderQueue->enqueue({m::rendering::RenderInfo::Mode::REWIND, OFFSET});

				m::rendering::renderSampleChannel(channel, /*scene=*/0, /*seqIsRunning=*/false);

				// Rendering should start over again at buffer[OFFSET]
				REQUIRE(channelShared.audioBuffer[OFFSET][0] == 1.0f);
			}

			SECTION("Stop, pitch == " + std::to_string(pitch))
			{
				// Point in audio buffer where the stop takes place
				const int OFFSET = 256;

				channelShared.renderQueue->enqueue({m::rendering::RenderInfo::Mode::STOP, OFFSET});

				m::rendering::renderSampleChannel(channel, /*scene=*/0, /*seqIsRunning=*/false);

				int numFramesWritten = 0;
				channelShared.audioBuffer.forEachFrame([&numFramesWritten](float* f, int)
				{
					if (f[0] != 0.0)
						numFramesWritten++;
				});

				REQUIRE(numFramesWritten == OFFSET);
			}
		}
	}
}