aboutsummaryrefslogtreecommitdiff
path: root/src/aomusicplayer.cpp
diff options
context:
space:
mode:
authorTrickyLeifa <date.epoch@gmail.com>2024-05-15 00:00:17 +0200
committerTrickyLeifa <date.epoch@gmail.com>2024-05-15 00:04:16 +0200
commitc9f52b7223685d2e7fca925594171f94dd8c6e3b (patch)
tree740bb32a40da98a4d52836432f59a16b31333900 /src/aomusicplayer.cpp
parent951766666621fa77e257e6b5616fe4ab1eb2a52f (diff)
Ported to CMake, ...
* Ported the project to CMake * Android and Mac support dropped for the time being. * Tests, BASS and Discord-RPC are now options * Restructured and reformated the project. * Merged `include` and `src` * Renamed `resource` to `data` * Renamed various files * External libraries headers are no longer included in `src` * Replaced header guards with #pragma once * Multiple refactors (keywords, headers) * Added Qt6 compatibility * Removed various unused functions and headers * Reworked AOPacket * When content is passed to AOPacket, it should be ensured that the content is already decoded. * Encoding/decoding are now static methods. * Fixed various memory leaks * Removed animation code for AOImage * AOImage is always using static images * Simplified ChatLogPiece
Diffstat (limited to 'src/aomusicplayer.cpp')
-rw-r--r--src/aomusicplayer.cpp191
1 files changed, 112 insertions, 79 deletions
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index 3f7c43ee..b9e6ab98 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -1,74 +1,92 @@
#include "aomusicplayer.h"
-#include "options.h"
-#include "bass.h"
#include "file_functions.h"
+#include "options.h"
-AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app)
-{
- m_parent = parent;
- ao_app = p_ao_app;
-}
+#include <bass.h>
+
+#include <QDebug>
+#include <QFuture>
+#include <QWidget>
+
+AOMusicPlayer::AOMusicPlayer(AOApplication *p_ao_app)
+ : ao_app(p_ao_app)
+{}
AOMusicPlayer::~AOMusicPlayer()
{
- for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
+ for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
+ {
BASS_ChannelStop(m_stream_list[n_stream]);
}
}
-QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
- int effect_flags)
+QString AOMusicPlayer::play(QString p_song, int channel, bool loop, int effect_flags)
{
- channel = channel % m_channelmax;
+ channel = channel % CHANNEL_COUNT;
if (channel < 0) // wtf?
+ {
return "[ERROR] Invalid Channel";
- unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
- BASS_UNICODE | BASS_ASYNCFILE;
+ }
+ unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE;
unsigned int streaming_flags = BASS_STREAM_AUTOFREE;
- if (loop) {
+ if (loop)
+ {
flags |= BASS_SAMPLE_LOOP;
streaming_flags |= BASS_SAMPLE_LOOP;
}
QString f_path = p_song;
DWORD newstream;
- if (f_path.startsWith("http")) {
-
- if (!Options::getInstance().streamingEnabled()) {
- BASS_ChannelStop(m_stream_list[channel]);
- return QObject::tr("[MISSING] Streaming disabled.");
+ if (f_path.startsWith("http"))
+ {
+ if (!Options::getInstance().streamingEnabled())
+ {
+ BASS_ChannelStop(m_stream_list[channel]);
+ return QObject::tr("[MISSING] Streaming disabled.");
}
QUrl l_url = QUrl(f_path);
newstream = BASS_StreamCreateURL(l_url.toEncoded().toStdString().c_str(), 0, streaming_flags, nullptr, 0);
}
- else {
+ else
+ {
f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
- if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx") )
- newstream = BASS_MusicLoad(FALSE,f_path.utf16(), 0, 0, flags, 1);
+ if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx"))
+ {
+ newstream = BASS_MusicLoad(FALSE, f_path.utf16(), 0, 0, flags, 1);
+ }
else
+ {
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
+ }
}
int error_code = BASS_ErrorGetCode();
if (Options::getInstance().audioOutputDevice() != "default")
+ {
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
+ }
QString d_path = f_path + ".txt";
- loop_start[channel] = 0;
- loop_end[channel] = 0;
+ m_loop_start[channel] = 0;
+ m_loop_end[channel] = 0;
if (loop && file_exists(d_path)) // Contains loop/etc. information file
{
QStringList lines = ao_app->read_file(d_path).split("\n");
bool seconds_mode = false;
- foreach (QString line, lines) {
+ foreach (QString line, lines)
+ {
QStringList args = line.split("=");
if (args.size() < 2)
+ {
continue;
+ }
QString arg = args[0].trimmed();
- if (arg == "seconds") {
- if (args[1].trimmed() == "true") {
+ if (arg == "seconds")
+ {
+ if (args[1].trimmed() == "true")
+ {
seconds_mode = true; // Use new epic behavior
continue;
}
@@ -86,64 +104,71 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
// Calculate the bytes for loop_start/loop_end to use with the sync proc
QWORD bytes;
- if (seconds_mode) {
- bytes =
- BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble());
+ if (seconds_mode)
+ {
+ bytes = BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble());
}
- else {
- bytes = static_cast<QWORD>(args[1].trimmed().toUInt() * sample_size *
- num_channels);
+ else
+ {
+ bytes = static_cast<QWORD>(args[1].trimmed().toUInt() * sample_size * num_channels);
}
if (arg == "loop_start")
- loop_start[channel] = bytes;
+ {
+ m_loop_start[channel] = bytes;
+ }
else if (arg == "loop_length")
- loop_end[channel] = loop_start[channel] + bytes;
+ {
+ m_loop_end[channel] = m_loop_start[channel] + bytes;
+ }
else if (arg == "loop_end")
- loop_end[channel] = bytes;
+ {
+ m_loop_end[channel] = bytes;
+ }
}
- qDebug() << "Found data file for song" << p_song << "length"
- << BASS_ChannelGetLength(newstream, BASS_POS_BYTE) << "loop start"
- << loop_start[channel] << "loop end" << loop_end[channel];
+ qDebug() << "Found data file for song" << p_song << "length" << BASS_ChannelGetLength(newstream, BASS_POS_BYTE) << "loop start" << m_loop_start[channel] << "loop end" << m_loop_end[channel];
}
- if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING) {
+ if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING)
+ {
DWORD oldstream = m_stream_list[channel];
- if (effect_flags & SYNC_POS) {
+ if (effect_flags & SYNC_POS)
+ {
BASS_ChannelLock(oldstream, true);
// Sync it with the new sample
- BASS_ChannelSetPosition(newstream,
- BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE),
- BASS_POS_BYTE);
+ BASS_ChannelSetPosition(newstream, BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE), BASS_POS_BYTE);
BASS_ChannelLock(oldstream, false);
}
- if ((effect_flags & FADE_OUT) && m_volume[channel] > 0) {
+ if ((effect_flags & FADE_OUT) && m_volume[channel] > 0)
+ {
// Fade out the other sample and stop it (due to -1)
- BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL | BASS_SLIDE_LOG,
- -1, 4000);
+ BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL | BASS_SLIDE_LOG, -1, 4000);
}
else
- BASS_ChannelStop(
- oldstream); // Stop the sample since we don't need it anymore
+ {
+ BASS_ChannelStop(oldstream); // Stop the sample since we don't need it anymore
+ }
}
else
+ {
BASS_ChannelStop(m_stream_list[channel]);
+ }
m_stream_list[channel] = newstream;
BASS_ChannelPlay(newstream, false);
- if (effect_flags & FADE_IN) {
+ if (effect_flags & FADE_IN)
+ {
// Fade in our sample
BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
- BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL,
- static_cast<float>(m_volume[channel] / 100.0f),
- 1000);
+ BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL, static_cast<float>(m_volume[channel] / 100.0f), 1000);
}
else
+ {
this->set_volume(m_volume[channel], channel);
+ }
- BASS_ChannelSetSync(newstream, BASS_SYNC_DEV_FAIL, 0,
- ao_app->BASSreset, 0);
+ BASS_ChannelSetSync(newstream, BASS_SYNC_DEV_FAIL, 0, ao_app->BASSreset, 0);
this->set_looping(loop, channel); // Have to do this here due to any
// crossfading-related changes, etc.
@@ -152,20 +177,25 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
QString p_song_clear = QUrl(p_song).fileName();
p_song_clear = p_song_clear.left(p_song_clear.lastIndexOf('.'));
- if (is_stop && channel == 0) { // don't send text on channels besides 0
+ if (is_stop && channel == 0)
+ { // don't send text on channels besides 0
return QObject::tr("None");
}
- if (error_code == BASS_ERROR_HANDLE) { // Cheap hack to see if file missing
+ if (error_code == BASS_ERROR_HANDLE)
+ { // Cheap hack to see if file missing
return QObject::tr("[MISSING] %1").arg(p_song_clear);
}
- if (p_song.startsWith("http") && channel == 0) {
+ if (p_song.startsWith("http") && channel == 0)
+ {
return QObject::tr("[STREAM] %1").arg(p_song_clear);
}
if (channel == 0)
+ {
return p_song_clear;
+ }
return "";
}
@@ -179,7 +209,8 @@ void AOMusicPlayer::set_muted(bool toggle)
{
m_muted = toggle;
// Update all volume based on the mute setting
- for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
+ for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
+ {
set_volume(m_volume[n_stream], n_stream);
}
}
@@ -189,13 +220,15 @@ void AOMusicPlayer::set_volume(int p_value, int channel)
m_volume[channel] = p_value;
// If muted, volume will always be 0
float volume = (m_volume[channel] / 100.0f) * !m_muted;
- if (channel < 0) {
- for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
- BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL,
- volume);
+ if (channel < 0)
+ {
+ for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
+ {
+ BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
}
}
- else {
+ else
+ {
BASS_ChannelSetAttribute(m_stream_list[channel], BASS_ATTRIB_VOL, volume);
}
}
@@ -212,35 +245,35 @@ void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
void AOMusicPlayer::set_looping(bool loop_song, int channel)
{
- if (!loop_song) {
+ if (!loop_song)
+ {
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
+ {
BASS_ChannelFlags(m_stream_list[channel], 0,
BASS_SAMPLE_LOOP); // remove the LOOP flag
- BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync[channel]);
- loop_sync[channel] = 0;
+ }
+ BASS_ChannelRemoveSync(m_stream_list[channel], m_loop_sync[channel]);
+ m_loop_sync[channel] = 0;
return;
}
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP,
BASS_SAMPLE_LOOP); // set the LOOP flag
- if (loop_sync[channel] != 0) {
+ if (m_loop_sync[channel] != 0)
+ {
BASS_ChannelRemoveSync(m_stream_list[channel],
- loop_sync[channel]); // remove the sync
- loop_sync[channel] = 0;
+ m_loop_sync[channel]); // remove the sync
+ m_loop_sync[channel] = 0;
}
- if (loop_start[channel] < loop_end[channel])
+ if (m_loop_start[channel] < m_loop_end[channel])
{
- //Loop when the endpoint is reached.
- loop_sync[channel] = BASS_ChannelSetSync(
- m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME,
- loop_end[channel], loopProc, &loop_start[channel]);
+ // Loop when the endpoint is reached.
+ m_loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, m_loop_end[channel], loopProc, &m_loop_start[channel]);
}
else
{
- //Loop when the end of the file is reached.
- loop_sync[channel] = BASS_ChannelSetSync(
- m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME,
- 0, loopProc, &loop_start[channel]);
+ // Loop when the end of the file is reached.
+ m_loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME, 0, loopProc, &m_loop_start[channel]);
}
}