Skip to content

Commit

Permalink
Refactor|Audio|Client: Locate music resource files only once per play…
Browse files Browse the repository at this point in the history
…back request

Revised playFile() so that only one attempt to locate referenced file
is made irrespective of the number playback interfaces tried.
  • Loading branch information
danij-deng committed Aug 10, 2015
1 parent 0f853b0 commit aebe330
Showing 1 changed file with 21 additions and 25 deletions.
46 changes: 21 additions & 25 deletions doomsday/apps/client/src/audio/s_mus.cpp
Expand Up @@ -122,55 +122,51 @@ static String tryFindMusicFile(Record const &definition)
return ""; // None found.
}

static dint playFile(String const &virtualOrNativePath, bool looped)
static dint playFile(String const &virtualOrNativePath, bool looped = false)
{
DENG2_ASSERT(::musAvail && App_AudioSystem().musicIsAvailable());

return App_AudioSystem().forAllInterfaces(AUDIO_IMUSIC, [&virtualOrNativePath, &looped] (void *ifs)
try
{
try
// Relative paths are relative to the native working directory.
String const path = (NativePath::workPath() / NativePath(virtualOrNativePath).expand()).withSeparators('/');
std::unique_ptr<FileHandle> hndl(&App_FileSystem().openFile(path, "rb"));

auto didPlay = App_AudioSystem().forAllInterfaces(AUDIO_IMUSIC, [&hndl, &looped] (void *ifs)
{
auto *iMusic = (audiointerface_music_t *) ifs;

// Relative paths are relative to the native working directory.
String path = (NativePath::workPath() / NativePath(virtualOrNativePath).expand()).withSeparators('/');
std::unique_ptr<FileHandle> hndl(&App_FileSystem().openFile(path, "rb"));
dsize const len = hndl->length();

// Does this interface offer buffered playback?
if(iMusic->Play && iMusic->SongBuffer)
{
// Buffer the data using the driver's own facility.
dsize const len = hndl->length();
hndl->read((duint8 *) iMusic->SongBuffer(len), len);
App_FileSystem().releaseFile(hndl->file());

return iMusic->Play(looped);
}
// Does this interface offer playback from a native file?
else if(iMusic->PlayFile)
{
// Write the data to disk and play from there.
String const fileName = composeBufferFilename();
String const bufPath = composeBufferFilename();

dsize len = hndl->length();
duint8 *buf = (duint8 *)M_Malloc(len);
hndl->read(buf, len);
F_Dump(buf, len, fileName.toUtf8().constData());
F_Dump(buf, len, bufPath.toUtf8().constData());
M_Free(buf); buf = nullptr;

App_FileSystem().releaseFile(hndl->file());

// Music maestro, if you please!
return iMusic->PlayFile(fileName.toUtf8().constData(), looped);
}
else
{
App_FileSystem().releaseFile(hndl->file());
return iMusic->PlayFile(bufPath.toUtf8().constData(), looped);
}
}
catch(FS1::NotFoundError const &)
{} // Ignore this error.
return 0; // Continue
});
return 0; // Continue.
});

App_FileSystem().releaseFile(hndl->file());
return didPlay;
}
catch(FS1::NotFoundError const &)
{} // Ignore this error.
return 0; // Continue.
}

/**
Expand Down

0 comments on commit aebe330

Please sign in to comment.