add playback of bass and rhythm tracks

This commit is contained in:
Chris Danford
2007-05-17 03:26:50 +00:00
parent 16194d7e53
commit ba616e4195
6 changed files with 140 additions and 31 deletions
+59 -19
View File
@@ -121,32 +121,72 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra
pPlayer2 = NULL;
pShared = NULL;
RString sError;
RageSoundReader *pSongReader = RageSoundReader_FileReader::OpenFile( pSong->GetMusicPath(), sError );
vector<RString> vsMusicFile;
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
pSongReader = new RageSoundReader_Extend( pSongReader );
pSongReader = new RageSoundReader_ThreadedBuffer( pSongReader );
pShared = pSongReader;
if( pSong->HasLeadTrack() )
vsMusicFile.push_back( pSong->GetMusicPath() );
FOREACH_ENUM( InstrumentTrack, it )
{
RageSoundReader *pLeadTrackReader = RageSoundReader_FileReader::OpenFile( pSong->GetLeadTrackPath(), sError );
if( it == InstrumentTrack_Guitar )
continue;
if( pSong->HasInstrumentTrack(it) )
vsMusicFile.push_back( pSong->GetInstrumentTrackPath(it) );
}
vector<RageSoundReader *> vpSounds;
FOREACH( RString, vsMusicFile, s )
{
RString sError;
RageSoundReader *pSongReader = RageSoundReader_FileReader::OpenFile( *s, sError );
vpSounds.push_back( pSongReader );
}
if( vpSounds.size() == 1 )
{
RageSoundReader *pSongReader = vpSounds[0];
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
pLeadTrackReader = new RageSoundReader_Extend( pLeadTrackReader );
pLeadTrackReader = new RageSoundReader_ThreadedBuffer( pLeadTrackReader );
pPlayer1 = pLeadTrackReader;
pSongReader = new RageSoundReader_Extend( pSongReader );
pSongReader = new RageSoundReader_ThreadedBuffer( pSongReader );
pShared = pSongReader;
}
else
{
RageSoundReader_Merge *pMerge = new RageSoundReader_Merge;
FOREACH( RageSoundReader *, vpSounds, so )
pMerge->AddSound( *so );
pMerge->Finish( SOUNDMAN->GetDriverSampleRate() );
RageSoundReader *pSongReader = pMerge;
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
pSongReader = new RageSoundReader_Extend( pSongReader );
pSongReader = new RageSoundReader_ThreadedBuffer( pSongReader );
pShared = pSongReader;
}
if( pSong->HasInstrumentTrack(InstrumentTrack_Guitar) )
{
RString sError;
RageSoundReader *pGuitarTrackReader = RageSoundReader_FileReader::OpenFile( pSong->GetInstrumentTrackPath(InstrumentTrack_Guitar), sError );
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
pGuitarTrackReader = new RageSoundReader_Extend( pGuitarTrackReader );
pGuitarTrackReader = new RageSoundReader_ThreadedBuffer( pGuitarTrackReader );
pPlayer1 = pGuitarTrackReader;
}
return;
if( pSongReader->GetNumChannels() <= 2 )
{
/* If we only have one track, return it as the shared track. */
pShared = pSongReader;
return;
}
//if( pSongReader->GetNumChannels() <= 2 )
//{
// /* If we only have one track, return it as the shared track. */
// pShared = pSongReader;
// return;
//}
// TODO: Make this work for player 2, and for 2 players
+19 -1
View File
@@ -920,7 +920,25 @@ bool MidiLoader::LoadFromDir( const RString &sDir, Song &out )
GetDirListing( sDir + RString("*guitar.mp3"), vsFiles );
GetDirListing( sDir + RString("*guitar.wav"), vsFiles );
if( vsFiles.size() > 0 )
out.m_sLeadTrackFile = vsFiles[0];
out.m_sInstrumentTrackFile[InstrumentTrack_Guitar] = vsFiles[0];
}
{
vector<RString> vsFiles;
GetDirListing( sDir + RString("*rhythm.ogg"), vsFiles );
GetDirListing( sDir + RString("*rhythm.mp3"), vsFiles );
GetDirListing( sDir + RString("*rhythm.wav"), vsFiles );
if( vsFiles.size() > 0 )
out.m_sInstrumentTrackFile[InstrumentTrack_Rhythm] = vsFiles[0];
}
{
vector<RString> vsFiles;
GetDirListing( sDir + RString("*bass.ogg"), vsFiles );
GetDirListing( sDir + RString("*bass.mp3"), vsFiles );
GetDirListing( sDir + RString("*bass.wav"), vsFiles );
if( vsFiles.size() > 0 )
out.m_sInstrumentTrackFile[InstrumentTrack_Bass] = vsFiles[0];
}
vector<RString> vsFiles;
+16 -2
View File
@@ -332,8 +332,22 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
else if( sValueName=="MUSIC" )
out.m_sMusicFile = sParams[1];
else if( sValueName=="LEADTRACK" )
out.m_sLeadTrackFile = sParams[1];
else if( sValueName=="INSTRUMENTTRACK" )
{
vector<RString> vs1;
split( sParams[1], ",", vs1 );
FOREACH_CONST( RString, vs1, s )
{
vector<RString> vs2;
split( *s, "=", vs2 );
if( vs2.size() >= 2 )
{
InstrumentTrack it = StringToInstrumentTrack( vs2[0] );
if( it != InstrumentTrack_Invalid )
out.m_sInstrumentTrackFile[it] = vs2[1];
}
}
}
else if( sValueName=="MUSICLENGTH" )
{
+12 -1
View File
@@ -52,7 +52,18 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.PutLine( ssprintf( "#LYRICSPATH:%s;", SmEscape(out.m_sLyricsFile).c_str() ) );
f.PutLine( ssprintf( "#CDTITLE:%s;", SmEscape(out.m_sCDTitleFile).c_str() ) );
f.PutLine( ssprintf( "#MUSIC:%s;", SmEscape(out.m_sMusicFile).c_str() ) );
f.PutLine( ssprintf( "#LEADTRACK:%s;", SmEscape(out.m_sLeadTrackFile).c_str() ) );
{
vector<RString> vs;
FOREACH_ENUM( InstrumentTrack, it )
if( out.HasInstrumentTrack(it) )
vs.push_back( InstrumentTrackToString(it) + "=" + out.m_sInstrumentTrackFile[it] );
if( !vs.empty() )
{
RString s = join( ",", vs );
f.PutLine( "#INSTRUMENTTRACK:" + s + ";\n" );
}
}
f.PutLine( ssprintf( "#OFFSET:%.3f;", out.m_Timing.m_fBeat0OffsetInSeconds ) );
f.PutLine( ssprintf( "#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds ) );
f.PutLine( ssprintf( "#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds ) );
+19 -5
View File
@@ -33,7 +33,7 @@
#include <set>
#include <float.h>
const int FILE_CACHE_VERSION = 156; // increment this to invalidate cache
const int FILE_CACHE_VERSION = 159; // increment this to invalidate cache
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
@@ -41,6 +41,15 @@ static Preference<float> g_fLongVerSongSeconds( "LongVerSongSeconds", 60*2.5f )
static Preference<float> g_fMarathonVerSongSeconds( "MarathonVerSongSeconds", 60*5.f );
static Preference<bool> g_BackUpAllSongSaves( "BackUpAllSongSaves", false );
static const char *InstrumentTrackNames[] = {
"Guitar",
"Rhythm",
"Bass",
};
XToString( InstrumentTrack );
StringToX( InstrumentTrack );
Song::Song()
{
FOREACH_BackgroundLayer( i )
@@ -362,7 +371,9 @@ void Song::TidyUpData()
ASSERT_M( m_sSongDir.Left(3) != "../", m_sSongDir ); /* meaningless */
FixupPath( m_sSongDir, "" );
FixupPath( m_sMusicFile, m_sSongDir );
FixupPath( m_sLeadTrackFile, m_sSongDir );
FOREACH_ENUM( InstrumentTrack, i )
if( !m_sInstrumentTrackFile[i].empty() )
FixupPath( m_sInstrumentTrackFile[i], m_sSongDir );
FixupPath( m_sBannerFile, m_sSongDir );
FixupPath( m_sLyricsFile, m_sSongDir );
FixupPath( m_sBackgroundFile, m_sSongDir );
@@ -1053,7 +1064,10 @@ bool Song::HasMusic() const
return m_sMusicFile != "" && IsAFile(GetMusicPath());
}
bool Song::HasBanner() const {return m_sBannerFile != "" && IsAFile(GetBannerPath()); }
bool Song::HasLeadTrack() const {return m_sLeadTrackFile != "" && IsAFile(GetLeadTrackPath()); }
bool Song::HasInstrumentTrack( InstrumentTrack it ) const
{
return m_sInstrumentTrackFile[it] != "" && IsAFile(GetInstrumentTrackPath(it));
}
bool Song::HasLyrics() const {return m_sLyricsFile != "" && IsAFile(GetLyricsPath()); }
bool Song::HasBackground() const {return m_sBackgroundFile != "" && IsAFile(GetBackgroundPath()); }
bool Song::HasCDTitle() const {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); }
@@ -1121,9 +1135,9 @@ RString Song::GetMusicPath() const
return GetSongAssetPath( m_sMusicFile, m_sSongDir );
}
RString Song::GetLeadTrackPath() const
RString Song::GetInstrumentTrackPath( InstrumentTrack it ) const
{
return GetSongAssetPath( m_sLeadTrackFile, m_sSongDir );
return GetSongAssetPath( m_sInstrumentTrackFile[it], m_sSongDir );
}
RString Song::GetBannerPath() const
+15 -3
View File
@@ -29,6 +29,17 @@ enum BackgroundLayer
};
#define FOREACH_BackgroundLayer( bl ) FOREACH_ENUM( BackgroundLayer, bl )
enum InstrumentTrack
{
InstrumentTrack_Guitar,
InstrumentTrack_Rhythm,
InstrumentTrack_Bass,
NUM_InstrumentTrack,
InstrumentTrack_Invalid
};
const RString& InstrumentTrackToString( InstrumentTrack it );
InstrumentTrack StringToInstrumentTrack( const RString& s );
struct LyricSegment
{
float m_fStartTime;
@@ -113,7 +124,8 @@ public:
RString m_sCredit;
RString m_sMusicFile;
RString m_sLeadTrackFile;
RString m_sInstrumentTrackFile[NUM_InstrumentTrack];
float m_fMusicLengthSeconds;
float m_fFirstBeat; // beat of first note
float m_fLastBeat; // beat of last note
@@ -130,7 +142,7 @@ public:
RString m_sCDTitleFile;
RString GetMusicPath() const;
RString GetLeadTrackPath() const;
RString GetInstrumentTrackPath( InstrumentTrack it ) const;
RString GetBannerPath() const;
RString GetLyricsPath() const;
RString GetBackgroundPath() const;
@@ -140,7 +152,7 @@ public:
bool m_bHasMusic, m_bHasBanner;
bool HasMusic() const;
bool HasLeadTrack() const;
bool HasInstrumentTrack( InstrumentTrack it ) const;
bool HasBanner() const;
bool HasBackground() const;
bool HasCDTitle() const;