Skip to content

Commit

Permalink
Fixed crashing bug when switching songs too quickly
Browse files Browse the repository at this point in the history
  • Loading branch information
KinoMyu committed Jan 15, 2018
1 parent 7597402 commit 84e462c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 21 deletions.
42 changes: 25 additions & 17 deletions src/HCADecodeService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,20 @@
#include "HCADecodeService.h"
#include "clHCA.h"

// Currently multithreaded decode is bugged, please use single thread for now
// Currently multithreaded decode is bugged due to out of order decoding
HCADecodeService::HCADecodeService(unsigned int numthreads)
: mainsem(numthreads),
: mainsem(1),
numthreads{1}, // Use single thread for now
datasem{ 0 },
finsem{0},
numchannels{0},
workingrequest{nullptr},
channels{nullptr},
shutdown{false}
{
if(numthreads > 0)
{
this->numthreads = numthreads;
}
else
{
this->numthreads = 1;
}
workingblocks = new int[numthreads];
for (unsigned int i = 0; i < numthreads; ++i)
workingblocks = new int[this->numthreads];
channels = new clHCA::stChannel[0x10 * this->numthreads];
for (unsigned int i = 0; i < this->numthreads; ++i)
{
workersem.emplace_back(0);
worker_threads.emplace_back(&HCADecodeService::Decode_Thread, this, i);
Expand All @@ -35,6 +30,7 @@ HCADecodeService::~HCADecodeService()
shutdown = true;
datasem.notify();
dispatchthread.join();
delete[] channels;
}

void HCADecodeService::cancel_decode(void* ptr)
Expand All @@ -59,6 +55,18 @@ void HCADecodeService::cancel_decode(void* ptr)
}
}

void HCADecodeService::wait_for_finish()
{
mutex.lock();
while(!filelist.empty() || !blocks.empty())
{
mutex.unlock();
finsem.wait();
mutex.lock();
}
mutex.unlock();
}

std::pair<void*, size_t> HCADecodeService::decode(const std::string& filename, DWORD samplenum)
{
clHCA hca(0xBC731A85, 0x0002B875);
Expand Down Expand Up @@ -91,11 +99,11 @@ void HCADecodeService::Main_Thread()
workingfile = std::move(it->second);
unsigned blocknum = it->first.second;
filelist.erase(it);
numchannels = workingfile.get_channelCount();
channels = new clHCA::stChannel[numchannels * numthreads];
numchannels = workingfile.get_channelCount();
workingfile.PrepDecode(channels, numthreads);
unsigned int blockCount = workingfile.get_blockCount();
for (unsigned int i = blocknum, j = 0; j < blockCount; ++i, ++j)
// initiate playback right away, and patch up "blip" cause by out of order decoding
for (unsigned int i = blocknum, j = 0; j < blockCount + blocknum; ++i, ++j)
{
blocks.push_back(i % blockCount);
}
Expand All @@ -121,8 +129,8 @@ void HCADecodeService::Main_Thread()
for (unsigned int i = 0; i < numthreads; ++i)
{
while (workingblocks[i] != -1); // busy wait until threads are finished
}
delete[] channels;
}
finsem.notify();
}
for (int i = 0; i < numthreads; ++i)
{
Expand Down
4 changes: 2 additions & 2 deletions src/HCADecodeService.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class HCADecodeService
~HCADecodeService();
void cancel_decode(void* ptr);
std::pair<void*, size_t> decode(const std::string& hcafilename, DWORD samplenum);
//void wait_for_finish();
void wait_for_finish();
private:
void Decode_Thread(int id);
void Main_Thread();
Expand All @@ -27,7 +27,7 @@ class HCADecodeService
std::deque<unsigned int> blocks;
int* workingblocks;
std::deque<Semaphore> workersem;
Semaphore mainsem, datasem;
Semaphore mainsem, datasem, finsem;
std::mutex mutex;
clHCA::stChannel* channels;
bool shutdown;
Expand Down
6 changes: 4 additions & 2 deletions src/clHCA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,9 @@ bool clHCA::Analyze(void*& wavptr, size_t& sz, const char* filenameHCA)
void clHCA::AsyncDecode(stChannel* channelsOffset, unsigned int blocknum, unsigned char* outputwavptr)
{
int seekhead = 0;
outputwavptr += 2 * blocknum * 8 * 128 * _channelCount + 44;
unsigned char* data = (unsigned char*)hcafileptr + (blocknum * _blockSize);
outputwavptr += 2 * blocknum * 8 * 128 * _channelCount + 44;
unsigned char* data = new unsigned char[_blockSize];
memcpy(data, (unsigned char*)hcafileptr + (blocknum * _blockSize), _blockSize);
// if(((unsigned char *)data)[_blockSize-2]==0x5E)_asm int 3
_cipher.Mask(data, _blockSize);
clData d(data, _blockSize);
Expand All @@ -673,6 +674,7 @@ void clHCA::AsyncDecode(stChannel* channelsOffset, unsigned int blocknum, unsign
}
}
}
delete[] data;
}

//--------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void MainWindow::setBGM(const QString& qStr)
std::string name = qStr.toUtf8().constData();
currSong = readablesong_to_filename[name];
BASS_ChannelPause(mix_stream);
dec.wait_for_finish();
BASS_Mixer_ChannelRemove(bgm->get_decode_channel());
bgm->unload();
bgm->load("res/" + currSong + "/bgm.hca");
Expand Down

0 comments on commit 84e462c

Please sign in to comment.