Skip to content

Commit 6864620

Browse files
authored
main upload
0 parents  commit 6864620

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+5685
-0
lines changed

Channel.cpp

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#include "Channel.h"
5+
6+
#include "PluginConfig.h"
7+
#include "Record.h"
8+
9+
Channel::Channel(const uint32_t channelFlags)
10+
: handle(BASS_StreamCreate(SV::kFrequency2, 1, channelFlags, STREAMPROC_PUSH, nullptr))
11+
, decoder(opus_decoder_create(SV::kFrequency, 1, &opusErrorCode))
12+
{
13+
if(this->handle == NULL) LogVoice("[sv:err:channel] : "
14+
"failed to create bass channel (code:%d)", BASS_ErrorGetCode());
15+
if(this->decoder == nullptr) LogVoice("[sv:err:channel] : "
16+
"failed to create opus decoder (code:%d)", this->opusErrorCode);
17+
18+
if(this->handle == NULL || this->decoder == nullptr)
19+
{
20+
if(this->decoder != nullptr) opus_decoder_destroy(this->decoder);
21+
if(this->handle != NULL) BASS_StreamFree(this->handle);
22+
throw std::exception();
23+
}
24+
}
25+
26+
Channel::~Channel() noexcept
27+
{
28+
if(this->playing) this->channelstop = true;
29+
//if(this->playing && this->stopCallback != nullptr)
30+
//this->stopCallback(*this);
31+
32+
opus_decoder_destroy(this->decoder);
33+
BASS_StreamFree(this->handle);
34+
}
35+
36+
HSTREAM Channel::GetHandle() const noexcept
37+
{
38+
return this->handle;
39+
}
40+
41+
void Channel::SetSpeaker(const uint16_t speaker) noexcept
42+
{
43+
this->speaker = speaker;
44+
}
45+
46+
bool Channel::HasSpeaker() const noexcept
47+
{
48+
return this->speaker != SV::kNonePlayer;
49+
}
50+
51+
uint16_t Channel::GetSpeaker() const noexcept
52+
{
53+
return this->speaker;
54+
}
55+
56+
bool Channel::IsActive() const noexcept
57+
{
58+
const auto bufferSize = BASS_ChannelGetData(this->handle, nullptr, BASS_DATA_AVAILABLE);
59+
return bufferSize != -1 && bufferSize != 0;
60+
}
61+
62+
void Channel::Reset() noexcept
63+
{
64+
BASS_ChannelPause(this->handle);
65+
BASS_ChannelSetPosition(this->handle, 0, BASS_POS_BYTE);
66+
opus_decoder_ctl(this->decoder, OPUS_RESET_STATE);
67+
68+
//if(this->playing && this->stopCallback != nullptr)
69+
//this->stopCallback(*this);
70+
71+
this->speaker = SV::kNonePlayer;
72+
this->expectedPacketNumber = 0;
73+
this->initialized = false;
74+
this->playing = false;
75+
}
76+
77+
void Channel::Push(const uint32_t packetNumber, const uint8_t* const dataPtr, const uint32_t dataSize) noexcept
78+
{
79+
if(!this->initialized || packetNumber == NULL)
80+
{
81+
LogVoice("[sv:dbg:channel:push] : init channel (speaker:%hu)", this->speaker);
82+
83+
BASS_ChannelPause(this->handle);
84+
BASS_ChannelSetPosition(this->handle, 0, BASS_POS_BYTE);
85+
opus_decoder_ctl(this->decoder, OPUS_RESET_STATE);
86+
87+
if(this->playing) this->channelstop = true;
88+
//if(this->playing && this->stopCallback != nullptr)
89+
//this->stopCallback(*this);
90+
91+
this->initialized = true;
92+
this->playing = false;
93+
}
94+
else if(packetNumber < this->expectedPacketNumber)
95+
{
96+
LogVoice("[sv:dbg:channel:push] : late packet to channel (speaker:%hu) "
97+
"(pack:%u;expPack:%u)", this->speaker, packetNumber, this->expectedPacketNumber);
98+
99+
return;
100+
}
101+
else if(packetNumber > this->expectedPacketNumber)
102+
{
103+
LogVoice("[sv:dbg:channel:push] : lost packet to channel (speaker:%hu) "
104+
"(pack:%u;expPack:%u)", this->speaker, packetNumber, this->expectedPacketNumber);
105+
106+
if(const int length = opus_decode(this->decoder, dataPtr, dataSize, this->decBuffer.data(),
107+
SV::kFrameSizeInSamples, true); length == static_cast<int>(SV::kFrameSizeInSamples))
108+
{
109+
BASS_StreamPutData(this->handle, this->decBuffer.data(), SV::kFrameSizeInBytes);
110+
111+
// put frame into playback buffer
112+
speex_echo_playback(Record::speexEchoState, this->decBuffer.data());
113+
}
114+
115+
goto gohere;
116+
}
117+
118+
if(const int length = opus_decode(this->decoder, dataPtr, dataSize, this->decBuffer.data(),
119+
SV::kFrameSizeInSamples, false); length == static_cast<int>(SV::kFrameSizeInSamples))
120+
{
121+
BASS_StreamPutData(this->handle, this->decBuffer.data(), SV::kFrameSizeInBytes);
122+
123+
// put frame into playback buffer
124+
speex_echo_playback(Record::speexEchoState, this->decBuffer.data());
125+
}
126+
127+
gohere:
128+
const auto channelStatus = BASS_ChannelIsActive(this->handle);
129+
const auto bufferSize = BASS_ChannelGetData(this->handle, nullptr, BASS_DATA_AVAILABLE);
130+
131+
if((channelStatus == BASS_ACTIVE_PAUSED || channelStatus == BASS_ACTIVE_STOPPED) &&
132+
bufferSize != -1 && bufferSize >= SV::kChannelPreBufferFramesCount * SV::kFrameSizeInBytes)
133+
{
134+
LogVoice("[sv:dbg:channel:push] : playing channel (speaker:%hu)", this->speaker);
135+
136+
BASS_ChannelPlay(this->handle, 0);
137+
138+
if(!this->playing) this->channelplay = true;
139+
//if(!this->playing && this->playCallback != nullptr)
140+
//this->playCallback(*this);
141+
142+
this->playing = true;
143+
}
144+
145+
this->expectedPacketNumber = packetNumber + 1;
146+
}
147+
148+
void Channel::SetPlayCallback(PlayCallback playCallback) noexcept
149+
{
150+
this->playCallback = std::move(playCallback);
151+
}
152+
153+
void Channel::SetStopCallback(StopCallback stopCallback) noexcept
154+
{
155+
this->stopCallback = std::move(stopCallback);
156+
}

Channel.h

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#pragma once
5+
6+
#include "../main.h"
7+
#include "../libbass.h"
8+
9+
#include "Header.h"
10+
11+
class Channel {
12+
Channel() = delete;
13+
Channel(const Channel&) = delete;
14+
Channel(Channel&&) = delete;
15+
Channel& operator=(const Channel&) = delete;
16+
Channel& operator=(Channel&&) = delete;
17+
18+
private:
19+
using PlayCallback = std::function<void(const Channel&)>;
20+
using StopCallback = std::function<void(const Channel&)>;
21+
22+
public:
23+
explicit Channel(uint32_t channelFlags);
24+
25+
~Channel() noexcept;
26+
27+
public:
28+
HSTREAM GetHandle() const noexcept;
29+
void SetSpeaker(uint16_t speaker) noexcept;
30+
bool HasSpeaker() const noexcept;
31+
uint16_t GetSpeaker() const noexcept;
32+
33+
bool IsActive() const noexcept;
34+
void Reset() noexcept;
35+
void Push(uint32_t packetNumber, const uint8_t* dataPtr, uint32_t dataSize) noexcept;
36+
37+
void SetPlayCallback(PlayCallback playCallback) noexcept;
38+
void SetStopCallback(StopCallback stopCallback) noexcept;
39+
40+
public:
41+
bool playing { false };
42+
bool channelplay { false };
43+
bool channelstop { false };
44+
45+
private:
46+
const HSTREAM handle;
47+
uint16_t speaker { SV::kNonePlayer };
48+
49+
PlayCallback playCallback;
50+
StopCallback stopCallback;
51+
52+
OpusDecoder* const decoder;
53+
std::array<opus_int16, SV::kFrameSizeInSamples> decBuffer;
54+
55+
uint32_t expectedPacketNumber { 0 };
56+
bool initialized { false };
57+
58+
int opusErrorCode { -1 };
59+
};
60+
61+
using ChannelPtr = std::unique_ptr<Channel>;
62+
#define MakeChannel std::make_unique<Channel>

ControlPacket.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#include "ControlPacket.h"
5+
6+
uint32_t ControlPacket::GetFullSize()
7+
{
8+
return sizeof(*this) + this->length;
9+
}

ControlPacket.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#pragma once
5+
6+
#include "include/util/Memory.hpp"
7+
8+
#pragma pack(push, 1)
9+
10+
struct ControlPacket
11+
{
12+
uint16_t packet;
13+
uint16_t length;
14+
uint8_t data[];
15+
16+
uint32_t GetFullSize();
17+
};
18+
19+
#pragma pack(pop)
20+
21+
using ControlPacketContainer = Memory::ObjectContainer<ControlPacket>;
22+
using ControlPacketContainerPtr = Memory::ObjectContainerPtr<ControlPacket>;
23+
#define MakeControlPacketContainer MakeObjectContainer(ControlPacket)

Effect.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#include "Effect.h"
5+
6+
Effect::Effect(const uint32_t type, const int priority,
7+
const void* const paramPtr, const uint32_t paramSize)
8+
: type(type), priority(priority), params(paramSize)
9+
{
10+
memcpy(this->params.data(), paramPtr, paramSize);
11+
}
12+
13+
Effect::~Effect() noexcept
14+
{
15+
for(const auto& fxHandle : this->fxHandles)
16+
{
17+
BASS_ChannelRemoveFX(fxHandle.first, fxHandle.second);
18+
}
19+
}
20+
21+
void Effect::Apply(const Channel& channel)
22+
{
23+
if(const auto fxHandle = BASS_ChannelSetFX(channel.GetHandle(),
24+
this->type/*, this->priority*/); fxHandle != NULL)
25+
{
26+
if(BASS_FXSetParameters(fxHandle, this->params.data()) == FALSE)
27+
{
28+
LogVoice("[sv:err:effect:apply] : failed "
29+
"to set parameters (code:%d)", BASS_ErrorGetCode());
30+
BASS_ChannelRemoveFX(channel.GetHandle(), fxHandle);
31+
}
32+
else
33+
{
34+
this->fxHandles[channel.GetHandle()] = fxHandle;
35+
}
36+
}
37+
else
38+
{
39+
LogVoice("[sv:err:effect:apply] : failed to create "
40+
"effect (code:%d)", BASS_ErrorGetCode());
41+
}
42+
}

Effect.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#pragma once
5+
6+
#include "../main.h"
7+
#include "../libbass.h"
8+
9+
#include "Channel.h"
10+
11+
class Effect {
12+
Effect() = delete;
13+
Effect(const Effect&) = delete;
14+
Effect(Effect&&) = delete;
15+
Effect& operator=(const Effect&) = delete;
16+
Effect& operator=(Effect&&) = delete;
17+
18+
public:
19+
explicit Effect(uint32_t type, int priority, const void* paramPtr, uint32_t paramSize);
20+
21+
~Effect() noexcept;
22+
23+
public:
24+
void Apply(const Channel& channel);
25+
26+
private:
27+
const uint32_t type;
28+
const int priority;
29+
std::vector<uint8_t> params;
30+
31+
std::map<HSTREAM, HFX> fxHandles;
32+
33+
};
34+
35+
using EffectPtr = std::unique_ptr<Effect>;
36+
#define MakeEffect std::make_unique<Effect>

GlobalStream.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#include "GlobalStream.h"
5+
6+
#include "StreamInfo.h"
7+
8+
GlobalStream::GlobalStream(const uint32_t color, std::string name) noexcept
9+
: Stream(NULL, StreamType::GlobalStream, color, std::move(name), -1.0) {}

GlobalStream.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// by Weikton 05.09.23
3+
//
4+
#pragma once
5+
6+
#include "Stream.h"
7+
8+
class GlobalStream : public Stream {
9+
GlobalStream() = delete;
10+
GlobalStream(const GlobalStream&) = delete;
11+
GlobalStream(GlobalStream&&) = delete;
12+
GlobalStream& operator=(const GlobalStream&) = delete;
13+
GlobalStream& operator=(GlobalStream&&) = delete;
14+
15+
public:
16+
explicit GlobalStream(uint32_t color, std::string name) noexcept;
17+
18+
~GlobalStream() noexcept = default;
19+
};
20+
21+
using GlobalStreamPtr = std::unique_ptr<GlobalStream>;
22+
#define MakeGlobalStream std::make_unique<GlobalStream>

0 commit comments

Comments
 (0)