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

Commit

Permalink
Repeat section added.
Browse files Browse the repository at this point in the history
  • Loading branch information
Flone-dnb committed Nov 2, 2019
1 parent 49b481c commit 48dc6d9
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 30 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Features:<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 section</b>. Click the right mouse button on the oscillogram to set the left bound for the repetition, click the right mouse button again to set the right bound and make a repetition section in which music will repeat.<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.<br>
- <b>"Repeat Track" / "Random Track"</b>. Use buttons under the volume slider to set "Repeat Track" / "Random Track" functions.<br>
6 changes: 3 additions & 3 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
- Speed up the process of adding the tracks.
- Add a little (non-modal window) "Tutorial" (with pictures) on first startup: tell user to drag'n'drop, Ctrl + F, RMB to create repeat section, RMB on tracks, FX.
And if user not finished th tutorial then show it again on next start. Or, if user checked "don't show again" don't show it again.
- 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.
- 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?
- 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.
Expand Down
2 changes: 1 addition & 1 deletion ide/BloodyPlayer.pro.user
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.1, 2019-11-02T00:13:12. -->
<!-- Written by QtCreator 4.10.1, 2019-11-02T18:43:46. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
Expand Down
5 changes: 5 additions & 0 deletions src/Controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ void Controller::setTrackPos(unsigned int graphPos)
pAudioService->setTrackPos(graphPos);
}

void Controller::setRepeatPoint(unsigned int graphPos)
{
pAudioService->setRepeatPoint(graphPos);
}

std::string Controller::getBloodyVersion()
{
return pAudioService->getBloodyVersion();
Expand Down
1 change: 1 addition & 0 deletions src/Controller/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Controller
void addTracks (std::vector<wchar_t*> paths);
void setVolume (float fNewVolume);
void setTrackPos (unsigned int graphPos);
void setRepeatPoint (unsigned int graphPos);


// Get
Expand Down
121 changes: 118 additions & 3 deletions src/Model/AudioService/audioservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,24 @@ AudioService::AudioService(MainWindow* pMainWindow)
{
sBloodyVersion = "1.16.1";


this->pMainWindow = pMainWindow;
pSystem = nullptr;
pRndGen = new std::mt19937_64( std::random_device{}() );
iCurrentlyDrawingTrackIndex = new size_t(0);


bMonitorTracks = false;
bIsSomeTrackPlaying = false;
bRepeatTrack = false;
bRandomNextTrack = false;
bDrawing = false;
bCurrentTrackPaused = false;


cRepeatSectionState = 0;


// FX
pPitch = nullptr;
pPitchForTime = nullptr;
Expand All @@ -46,6 +52,7 @@ AudioService::AudioService(MainWindow* pMainWindow)
fCurrentSpeedByPitch = 1.0f;
fCurrentSpeedByTime = 1.0f;


FMODinit();
}

Expand Down Expand Up @@ -469,6 +476,13 @@ void AudioService::playTrack(size_t iTrackIndex, bool bDontLockMutex)
vTracksHistory.erase( vTracksHistory.begin() );
}
}

if (cRepeatSectionState != 0)
{
pMainWindow->eraseRepeatSection();

cRepeatSectionState = 0;
}
}
else
{
Expand Down Expand Up @@ -503,12 +517,26 @@ void AudioService::setTrackPos(unsigned int graphPos)
// track->getMaxValueOnGraph() - 100%
// graphPos - x%

// cast to unsigned long long to avoid overflow
double fPosMult = graphPos / static_cast<double>(tracks[iCurrentlyPlayingTrackIndex]->getMaxValueOnGraph());
// cast to avoid overflow
unsigned int iPosInMS = static_cast<unsigned int>(tracks[iCurrentlyPlayingTrackIndex]->getLengthInMS() * fPosMult);
if ( tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS(iPosInMS) )

if (cRepeatSectionState == 2)
{
pMainWindow->setCurrentPos(fPosMult, tracks[iCurrentlyPlayingTrackIndex]->getCurrentTime());
if ( (iPosInMS > iFirstRepeatTimePos) && (iPosInMS < iSecondRepeatTimePos) )
{
if ( tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS(iPosInMS) )
{
pMainWindow->setCurrentPos(fPosMult, tracks[iCurrentlyPlayingTrackIndex]->getCurrentTime());
}
}
}
else
{
if ( tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS(iPosInMS) )
{
pMainWindow->setCurrentPos(fPosMult, tracks[iCurrentlyPlayingTrackIndex]->getCurrentTime());
}
}
}

Expand All @@ -522,6 +550,70 @@ void AudioService::setTrackPos(unsigned int graphPos)
mtxTracksVec.unlock();
}

void AudioService::setRepeatPoint(unsigned int graphPos)
{
mtxTracksVec.lock();

if ( (tracks.size() > 0) && (bIsSomeTrackPlaying || bCurrentTrackPaused) )
{
// track->getMaxValueOnGraph() - 100%
// graphPos - x%

double fPosMult = graphPos / static_cast<double>(tracks[iCurrentlyPlayingTrackIndex]->getMaxValueOnGraph());

if (cRepeatSectionState == 0)
{
// Set the first point
pMainWindow->setRepeatPoint(true, fPosMult);

cRepeatSectionState = 1;

unsigned int iPosInMS = static_cast<unsigned int>(tracks[iCurrentlyPlayingTrackIndex]->getLengthInMS() * fPosMult);
iFirstRepeatTimePos = iPosInMS;


// Set track pos
if ( tracks[iCurrentlyPlayingTrackIndex]->getPositionInMS() < iFirstRepeatTimePos )
{
if ( tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS(iFirstRepeatTimePos) )
{
pMainWindow->setCurrentPos(fPosMult, tracks[iCurrentlyPlayingTrackIndex]->getCurrentTime());
}
}
}
else if (cRepeatSectionState == 1)
{
// One point already on graph, set the second one
pMainWindow->setRepeatPoint(false, fPosMult);

// Done
cRepeatSectionState = 2;

unsigned int iPosInMS = static_cast<unsigned int>(tracks[iCurrentlyPlayingTrackIndex]->getLengthInMS() * fPosMult);
iSecondRepeatTimePos = iPosInMS;


// Set track pos
if ( tracks[iCurrentlyPlayingTrackIndex]->getPositionInMS() > iSecondRepeatTimePos )
{
if ( tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS(iFirstRepeatTimePos) )
{
pMainWindow->setCurrentPos(fPosMult, tracks[iCurrentlyPlayingTrackIndex]->getCurrentTime());
}
}
}
else
{
// User pressed RMB again, erase section
pMainWindow->eraseRepeatSection();

cRepeatSectionState = 0;
}
}

mtxTracksVec.unlock();
}

std::string AudioService::getBloodyVersion()
{
return sBloodyVersion;
Expand Down Expand Up @@ -1345,6 +1437,29 @@ void AudioService::monitorTrack()
}
else
{
if (cRepeatSectionState == 2)
{
if ( tracks[iCurrentlyPlayingTrackIndex]->getPositionInMS() > iSecondRepeatTimePos - MAX_TIME_ERROR_MS )
{
for (float i = fCurrentVolume; i >= 0.0f; i-= 0.01f)
{
tracks[iCurrentlyPlayingTrackIndex]->setVolume(i);

std::this_thread::sleep_for (std::chrono::milliseconds(2));
}

tracks[iCurrentlyPlayingTrackIndex]->setPositionInMS (iFirstRepeatTimePos);

for (float i = 0; i <= fCurrentVolume; i+= 0.01f)
{
tracks[iCurrentlyPlayingTrackIndex]->setVolume(i);

std::this_thread::sleep_for (std::chrono::milliseconds(2));
}
}
}


// track->getLengthInMS() - 1.0
// track->getPositionInMS() - x

Expand Down
30 changes: 19 additions & 11 deletions src/Model/AudioService/audioservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class AudioService
void addTracks (std::vector<wchar_t*> paths);
void setVolume (float fNewVolume);
void setTrackPos (unsigned int graphPos);
void setRepeatPoint (unsigned int graphPos);


// Get
Expand Down Expand Up @@ -155,6 +156,24 @@ class AudioService
bool bDrawing;


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


// Tracks
std::vector<Track*> tracks;
std::vector<Track*> vTracksHistory;


// Repeat section
char cRepeatSectionState;
unsigned int iFirstRepeatTimePos;
unsigned int iSecondRepeatTimePos;



std::mutex mtxTracksVec;
std::mutex mtxThreadLoadAddTrack;
std::mutex mtxLoadThreadDone;
Expand All @@ -176,15 +195,4 @@ class AudioService
bool bRepeatTrack;
bool bRandomNextTrack;
bool bMonitorTracks;


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


// Tracks
std::vector<Track*> tracks;
std::vector<Track*> vTracksHistory;
};
Loading

0 comments on commit 48dc6d9

Please sign in to comment.