Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Commit

Permalink
Added search on Ctrl + F.
Browse files Browse the repository at this point in the history
  • Loading branch information
Flone-dnb committed Nov 2, 2019
1 parent eac75fc commit 27af4e9
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 57 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Bloody Player is an audio player created using Qt and FMOD.<br>
<img width="650" height="400" src="screenshot.png">
</p>
Features:<br>
- Dark-red design.<br>
- Drag'n'Drop. Drag'n'Drop tracks right to the Bloody Player window to add tracks to the tracklist. You can also drag'n'drop folders to add tracks from it.<br>
- Tracklists. Save the current tracklist and open it later.<br>
- SFX. Add sound effects or load your VST plugin.<br>
- Tracklist management. Move tracks in the tracklist or delete some of them by right-clicking on the track or using hotkeys.<br>
- Oscillogram. Click on the horizontal oscillogram displaying amplitude from time to change the current track's position.<br>
- "Repeat Track" / "Random Track". Use buttons under the volume slider to set "Repeat Track" / "Random Track" functions.<br>
- <b>Drag'n'Drop</b>. Drag'n'Drop tracks right to the Bloody Player window to add tracks to the tracklist. You can also drag'n'drop folders to add tracks from it.<br>
- <b>Tracklists</b>. Save the current tracklist and open it later.<br>
- <b>SFX</b>. Add sound effects or load your VST plugin.<br>
- <b>Tracklist management</b>. Move tracks in the tracklist or delete some of them by right-clicking on the track or using hotkeys.<br>
- <b>Search</b>. Use Ctrl + F to open the search window to search for the desired track in the tracklist.
- <b>Oscillogram</b>. Click on the horizontal oscillogram displaying amplitude from time to change the current track's position.<br>
- <b>"Repeat Track" / "Random Track"</b>. Use buttons under the volume slider to set "Repeat Track" / "Random Track" functions.<br>
6 changes: 2 additions & 4 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
- Speed up the process of adding the tracks.
- Add a history of played tracks so the 'prev' button will get back to actually previous track even if 'random track' function is selected.
- Speed up the process of adding the tracks.
- When adding music, we need to add it in the same order in which it was in the folder.
- Change random to random_device?
- Do something with color banding.
- Seems like with 'speed (by pitch)' effect we also need to increase mid-high frequencies on like 3-4 dB and maybe do the same thing with the low and the mid-low.
- Add bounds in which track will repeat by clicking RMB on the oscillogram. Track's volume in the transition from end bound to start bound will change?
- Add a history of played tracks so the 'prev' button will get back to actually previous track even if 'random track' function is selected.
- After the tracklist was cleared volume returns to the default value of 75%, we don't want that, don't change master volume when tracklist is clear and allow to change it if tracklist is clear.
- Add winsock2 and make 'Check for Updates' button in menu (see https://stackoverflow.com/questions/39931347/simple-http-get-with-winsock and https://github.com/VioletGiraffe/github-releases-autoupdater).
- With winsock2 create a server and if another audio file is being opened a new instance of Player will check if one is running and if true then this new track will be sent to currently running instance.
- Make better icons for buttons.
- Add gain (fader) DSP.
- Add multi-band EQ.
- Add the Ctrl + F shortcut to show the 'Search by Keyword' window and set focus on the track with the match. 'Search by Keyword' will also have a 'next match' and 'prev match' buttons.
- On every startup check if the Player is associated with the audio formats in windows and if not then ask to associate.
3 changes: 3 additions & 0 deletions ide/BloodyPlayer.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOURCES += \
../src/Model/Track/track.cpp \
../src/View/AboutWindow/aboutwindow.cpp \
../src/View/FXWindow/fxwindow.cpp \
../src/View/SearchWindow/searchwindow.cpp \
../src/View/TrackList/tracklist.cpp \
../src/View/TrackWidget/trackwidget.cpp \
../src/View/VSTWindow/vstwindow.cpp \
Expand All @@ -47,6 +48,7 @@ HEADERS += \
../src/View/AboutWindow/aboutwindow.h \
../src/View/FXWindow/fxwindow.h \
../src/View/MainWindow/mainwindow.h \
../src/View/SearchWindow/searchwindow.h \
../src/View/TrackList/tracklist.h \
../src/View/TrackWidget/trackwidget.h \
../src/View/VSTWindow/vstwindow.h \
Expand All @@ -57,6 +59,7 @@ FORMS += \
../src/View/AboutWindow/aboutwindow.ui \
../src/View/FXWindow/fxwindow.ui \
../src/View/MainWindow/mainwindow.ui \
../src/View/SearchWindow/searchwindow.ui \
../src/View/TrackList/tracklist.ui \
../src/View/TrackWidget/trackwidget.ui \
../src/View/VSTWindow/vstwindow.ui \
Expand Down
15 changes: 15 additions & 0 deletions src/Controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ void Controller::saveTracklist(std::wstring pathToTracklist)
pAudioService->saveTracklist(pathToTracklist);
}

void Controller::searchFindPrev()
{
pAudioService->searchFindPrev ();
}

void Controller::searchFindNext()
{
pAudioService->searchFindNext ();
}

void Controller::searchTextSet(const std::wstring &sKeyword)
{
pAudioService->searchTextSet (sKeyword);
}

void Controller::setPan(float fPan)
{
pAudioService->setPan(fPan);
Expand Down
7 changes: 7 additions & 0 deletions src/Controller/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ class Controller
void saveTracklist (std::wstring pathToTracklist);


// Search

void searchFindPrev ();
void searchFindNext ();
void searchTextSet (const std::wstring& sKeyword);


// FX

void setPan (float fPan);
Expand Down
97 changes: 96 additions & 1 deletion src/Model/AudioService/audioservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void AudioService::FMODinit()

void AudioService::addTrack(const wchar_t *pFilePath)
{
Track* pNewTrack = new Track(pFilePath, pMainWindow, pSystem);
Track* pNewTrack = new Track(pFilePath, getTrackName(pFilePath), pMainWindow, pSystem);
if ( !pNewTrack->setupTrack() )
{
delete pNewTrack;
Expand Down Expand Up @@ -1112,6 +1112,90 @@ void AudioService::moveUp(size_t iTrackIndex)
mtxTracksVec.unlock();
}

void AudioService::searchFindPrev()
{
if (vSearchResult.size() > 0)
{
if (bFirstSearchAfterKeyChange == false)
{
if (iCurrentPosInSearchVec == 0)
{
iCurrentPosInSearchVec = vSearchResult.size() - 1;
}
else
{
iCurrentPosInSearchVec--;
}
}


if ( !(bFirstSearchAfterKeyChange == false && vSearchResult.size() == 1) ) // do not select again if matches == 1 && already selected
{
pMainWindow->setFocusOnTrack ( vSearchResult[iCurrentPosInSearchVec] );
pMainWindow->searchSetSelected ( vSearchResult[iCurrentPosInSearchVec] );
}


bFirstSearchAfterKeyChange = false;
}
}

void AudioService::searchFindNext()
{
if (vSearchResult.size() > 0)
{
if (bFirstSearchAfterKeyChange == false)
{
if (iCurrentPosInSearchVec == vSearchResult.size() - 1)
{
iCurrentPosInSearchVec = 0;
}
else
{
iCurrentPosInSearchVec++;
}
}


if ( !(bFirstSearchAfterKeyChange == false && vSearchResult.size() == 1) ) // do not select again if matches == 1 && already selected
{
pMainWindow->setFocusOnTrack ( vSearchResult[iCurrentPosInSearchVec] );
pMainWindow->searchSetSelected ( vSearchResult[iCurrentPosInSearchVec] );
}


bFirstSearchAfterKeyChange = false;
}
}

void AudioService::searchTextSet(const std::wstring &sKeyword)
{
mtxTracksVec.lock();


vSearchResult.clear();
iCurrentPosInSearchVec = 0;

if (sKeyword != L"")
{
for (size_t i = 0; i < tracks.size(); i++)
{
if ( findCaseInsensitive( tracks[i]->getTrackName(), const_cast<std::wstring&>(sKeyword)) != std::string::npos )
{
vSearchResult.push_back(i);
}
}
}

bFirstSearchAfterKeyChange = true;


mtxTracksVec.unlock();


pMainWindow->setSearchMatchCount (vSearchResult.size());
}

void AudioService::repeatTrack()
{
bRepeatTrack = !bRepeatTrack;
Expand Down Expand Up @@ -1480,6 +1564,17 @@ int AudioService::interpret24bitAsInt32(char byte0, char byte1, char byte2)
return ( (byte0 << 24) | (byte1 << 16) | (byte2 << 8) ) >> 8;
}

size_t AudioService::findCaseInsensitive(std::wstring& sText, std::wstring& sKeyword)
{
// All to lower case

std::transform(sText.begin(), sText.end(), sText.begin(), ::tolower);

std::transform(sKeyword.begin(), sKeyword.end(), sKeyword.begin(), ::tolower);

return sText.find(sKeyword);
}

void AudioService::threadAddTracks(std::vector<wchar_t*>* paths, size_t iStart, size_t iStop, bool* done, int* allCount, int all)
{
for (size_t i = iStart; i <= iStop; i++)
Expand Down
26 changes: 20 additions & 6 deletions src/Model/AudioService/audioservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class AudioService

// Main functions

void playTrack (size_t iTrackIndex, bool bDontLockMutex = false);
void nextTrack (bool bDontLockMutex = false, bool bRandomNextTrack = false);
void pauseTrack ();
void stopTrack ();
void prevTrack ();
void playTrack (size_t iTrackIndex, bool bDontLockMutex = false);
void nextTrack (bool bDontLockMutex = false, bool bRandomNextTrack = false);
void pauseTrack ();
void stopTrack ();
void prevTrack ();


// Buttons under the volume slider
Expand All @@ -64,6 +64,13 @@ class AudioService
void moveUp (size_t iTrackIndex);


// Search

void searchFindPrev ();
void searchFindNext ();
void searchTextSet (const std::wstring& sKeyword);


// FX

void setPan (float fPan);
Expand Down Expand Up @@ -104,6 +111,7 @@ class AudioService
// Functions for execution in a separete thread
void threadAddTracks (std::vector<wchar_t*>* paths, size_t iStart, size_t iStop, bool* done, int* allCount, int all);
void addTrack (const wchar_t* pFilePath);
std::wstring getTrackName (const wchar_t* pFilePath);

// Will switch to next track if one's ended
void monitorTrack ();
Expand All @@ -116,6 +124,9 @@ class AudioService
float* rawBytesToPCM24_0_1 (char* pBuffer, unsigned int iBufferSizeInBytes);
int interpret24bitAsInt32 (char byte0, char byte1, char byte2);

// Used in search()
size_t findCaseInsensitive(std::wstring& sText, std::wstring& sKeyword);




Expand Down Expand Up @@ -167,7 +178,10 @@ class AudioService
bool bMonitorTracks;



// Searcy
std::vector<size_t> vSearchResult;
size_t iCurrentPosInSearchVec;
bool bFirstSearchAfterKeyChange;


std::vector<Track*> tracks;
Expand Down
26 changes: 22 additions & 4 deletions src/Model/Track/track.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
#include "track.h"

// STL
#include <fstream>
#include <vector>
#include <codecvt>

// Custom
#include "../src/View/MainWindow/mainwindow.h"
#include "../ext/FMOD/inc/fmod.hpp"
#include "../ext/FMOD/inc/fmod_errors.h"
#include "../src/globalparams.h"

// Other
#include <windows.h>

Track::Track(const wchar_t* pFilePath, MainWindow *pMainWindow, FMOD::System* pSystem)
Track::Track(const wchar_t* pFilePath, const std::wstring& sTrackName, MainWindow *pMainWindow, FMOD::System* pSystem)
{
pChannel = nullptr;
pSound = nullptr;
this->pFilePath = pFilePath;
this->sTrackName = sTrackName;

this->pMainWindow = pMainWindow;
this->pSystem = pSystem;
Expand Down Expand Up @@ -48,7 +53,9 @@ bool Track::setupTrack()
result = pSystem->createStream(filePathInUTF8, FMOD_DEFAULT | FMOD_LOOP_OFF | FMOD_ACCURATETIME, nullptr, &pSound);
if (result)
{
pMainWindow->showMessageBox( true, std::string("Track::setTrack::FMOD::System::createStream() failed. Error: ") + std::string(FMOD_ErrorString(result)) );
pMainWindow->showWMessageBox( true, std::wstring(L"Track::setupTrack::FMOD::System::createStream() failed.\n\n"
"Can't load the file \"" + std::wstring(pFilePath) + L"\".\n\n"
"Error: ") + stringToWString(std::string(FMOD_ErrorString(result))) );
return false;
}

Expand All @@ -59,7 +66,7 @@ bool Track::setupTrack()
result = pSound->getFormat(&type, &formatType, nullptr, nullptr);
if (result)
{
pMainWindow->showMessageBox( true, std::string("Track::setTrack::FMOD::Sound::getFormat() failed. Error: ") + std::string(FMOD_ErrorString(result)) );
pMainWindow->showMessageBox( true, std::string("Track::setupTrack::FMOD::Sound::getFormat() failed. Error: ") + std::string(FMOD_ErrorString(result)) );
return false;
}

Expand Down Expand Up @@ -214,6 +221,11 @@ const wchar_t* Track::getFilePath()
return pFilePath;
}

std::wstring &Track::getTrackName()
{
return sTrackName;
}

unsigned int Track::getMaxValueOnGraph()
{
return iMaxValueOnGraph;
Expand Down Expand Up @@ -1045,7 +1057,13 @@ int Track::tellSamplingRate(bool bit1, bool bit2)
else if (bitString == "01") return 48000;
else if (bitString == "10") return 32000;

return -1;
return -1;
}

std::wstring Track::stringToWString(const std::string &str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
return convert.from_bytes(str);
}


Expand Down
8 changes: 7 additions & 1 deletion src/Model/Track/track.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Track

public:

Track(const wchar_t* pFilePath, MainWindow* pMainWindow, FMOD::System* pSystem);
Track(const wchar_t* pFilePath, const std::wstring& sTrackName, MainWindow* pMainWindow, FMOD::System* pSystem);



Expand Down Expand Up @@ -102,6 +102,7 @@ class Track

char getPCMSamples (char* pBuff, unsigned int amountInBytes, unsigned int *pActualRead, char* pPcmFormat);
const wchar_t* getFilePath ();
std::wstring& getTrackName ();



Expand All @@ -116,6 +117,10 @@ class Track
int tellBitRate (bool bit1, bool bit2, bool bit3, bool bit4);
int tellSamplingRate (bool bit1, bool bit2);

// Convert

std::wstring stringToWString (const std::string& str);




Expand All @@ -131,6 +136,7 @@ class Track
FMOD::System* pSystem;


std::wstring sTrackName;
std::string format;
std::string pcmFormat;

Expand Down
Loading

0 comments on commit 27af4e9

Please sign in to comment.