Add missing function headers
Signed-off-by: Mahyar Koshkouei <deltabeard@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Return string describing error number. Extends strerror to include some
|
||||
* custom errors used in ctrmus.
|
||||
*
|
||||
* \param err Error number.
|
||||
*/
|
||||
char* ctrmus_strerror(int err)
|
||||
{
|
||||
char* error;
|
||||
|
||||
@@ -5,11 +5,25 @@
|
||||
#define DECODER_INIT_FAIL 1001
|
||||
#define FILE_NOT_SUPPORTED 1002
|
||||
|
||||
/**
|
||||
* Struct to help error handling across threads.
|
||||
*/
|
||||
struct errInfo_t
|
||||
{
|
||||
/* errno code or from defines listed above */
|
||||
volatile int* error;
|
||||
Handle* failEvent;
|
||||
|
||||
/* Extra information regarding error (Must be NULL if unused) */
|
||||
volatile char* errstr;
|
||||
|
||||
/* Event to trigger on error */
|
||||
Handle* failEvent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return string describing error number. Extends strerror to include some
|
||||
* custom errors used in ctrmus.
|
||||
*
|
||||
* \param err Error number.
|
||||
*/
|
||||
char* ctrmus_strerror(int err);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#include <./dr_libs/dr_flac.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "flac.h"
|
||||
|
||||
|
||||
340
source/main.c
340
source/main.c
@@ -22,6 +22,185 @@
|
||||
|
||||
volatile bool runThreads = true;
|
||||
|
||||
/**
|
||||
* Prints the current key mappings to stdio.
|
||||
*/
|
||||
static void showControls(void)
|
||||
{
|
||||
printf("Button mappings:\n"
|
||||
"Pause: L+R or L+Up\n"
|
||||
"Stop: L+B\n"
|
||||
"A: Open File\n"
|
||||
"B: Go up folder\n"
|
||||
"Start: Exit\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the playback thread to return any error messages that it may
|
||||
* encounter.
|
||||
*
|
||||
* \param infoIn Struct containing addresses of the event, the error code,
|
||||
* and an optional error string.
|
||||
*/
|
||||
void playbackWatchdog(void* infoIn)
|
||||
{
|
||||
struct watchdogInfo* info = infoIn;
|
||||
|
||||
while(runThreads)
|
||||
{
|
||||
svcWaitSynchronization(*info->errInfo->failEvent, U64_MAX);
|
||||
svcClearEvent(*info->errInfo->failEvent);
|
||||
consoleSelect(info->screen);
|
||||
|
||||
if(*info->errInfo->error != 0)
|
||||
{
|
||||
printf("Error %d: %s", *info->errInfo->error,
|
||||
ctrmus_strerror(*info->errInfo->error));
|
||||
|
||||
if(info->errInfo->errstr != NULL)
|
||||
{
|
||||
printf(" %s", info->errInfo->errstr);
|
||||
delete(info->errInfo->errstr);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the currently playing file (if there is one) and play another file.
|
||||
*
|
||||
* \param ep_file File to play.
|
||||
* \param playbackInfo Information that the playback thread requires to
|
||||
* play file.
|
||||
*/
|
||||
static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo)
|
||||
{
|
||||
s32 prio;
|
||||
static Thread thread = NULL;
|
||||
|
||||
/**
|
||||
* If music is playing, stop it. Only one playback thread should be playing
|
||||
* at any time.
|
||||
*/
|
||||
if(thread != NULL)
|
||||
{
|
||||
/* Tell the thread to stop playback before we join it */
|
||||
stopPlayback();
|
||||
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
thread = NULL;
|
||||
|
||||
/* free allocated file string */
|
||||
delete(playbackInfo->file);
|
||||
}
|
||||
|
||||
if(ep_file == NULL || playbackInfo == NULL)
|
||||
return 0;
|
||||
|
||||
playbackInfo->file = strdup(ep_file);
|
||||
printf("Playing: %s\n", playbackInfo->file);
|
||||
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate(playFile, playbackInfo, 32 * 1024, prio - 1, -2, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* List current directory.
|
||||
*
|
||||
* \param from First entry in directory to list.
|
||||
* \param max Maximum number of entries to list. Must be > 0.
|
||||
* \param select File to show as selected. Must be > 0.
|
||||
* \return Number of entries listed or negative on error.
|
||||
*/
|
||||
static int listDir(int from, int max, int select)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
int fileNum = 0;
|
||||
int listed = 0;
|
||||
char* wd = getcwd(NULL, 0);
|
||||
|
||||
if(wd == NULL)
|
||||
goto err;
|
||||
|
||||
consoleClear();
|
||||
printf("Dir: %.33s\n", wd);
|
||||
|
||||
if((dp = opendir(wd)) == NULL)
|
||||
goto err;
|
||||
|
||||
if(from == 0)
|
||||
{
|
||||
printf("%c../\n", select == 0 ? '>' : ' ');
|
||||
listed++;
|
||||
}
|
||||
|
||||
while((ep = readdir(dp)) != NULL)
|
||||
{
|
||||
fileNum++;
|
||||
|
||||
if(fileNum <= from)
|
||||
continue;
|
||||
|
||||
listed++;
|
||||
|
||||
printf("%c%s%.37s%s\n",
|
||||
select == fileNum ? '>' : ' ',
|
||||
ep->d_type == DT_DIR ? "\x1b[34;1m" : "",
|
||||
ep->d_name,
|
||||
ep->d_type == DT_DIR ? "/\x1b[0m" : "");
|
||||
|
||||
if(fileNum == max + from)
|
||||
break;
|
||||
}
|
||||
|
||||
if(closedir(dp) != 0)
|
||||
goto err;
|
||||
|
||||
out:
|
||||
free(wd);
|
||||
return listed;
|
||||
|
||||
err:
|
||||
listed = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of files in current working folder
|
||||
*
|
||||
* \return Number of files in current working folder, -1 on failure with
|
||||
* errno set.
|
||||
*/
|
||||
int getNumberFiles(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
int ret = 0;
|
||||
|
||||
if((dp = opendir(".")) == NULL)
|
||||
goto err;
|
||||
|
||||
while((ep = readdir(dp)) != NULL)
|
||||
ret++;
|
||||
|
||||
closedir(dp);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
err:
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PrintConsole topScreen;
|
||||
@@ -262,164 +441,3 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void showControls(void)
|
||||
{
|
||||
printf("Button mappings:\n"
|
||||
"Pause: L+R or L+Up\n"
|
||||
"Stop: L+B\n"
|
||||
"A: Open File\n"
|
||||
"B: Go up folder\n"
|
||||
"Start: Exit\n");
|
||||
}
|
||||
|
||||
void playbackWatchdog(void* infoIn)
|
||||
{
|
||||
struct watchdogInfo* info = infoIn;
|
||||
|
||||
while(runThreads)
|
||||
{
|
||||
svcWaitSynchronization(*info->errInfo->failEvent, U64_MAX);
|
||||
svcClearEvent(*info->errInfo->failEvent);
|
||||
consoleSelect(info->screen);
|
||||
|
||||
if(*info->errInfo->error != 0)
|
||||
{
|
||||
printf("Error %d: %s", *info->errInfo->error,
|
||||
ctrmus_strerror(*info->errInfo->error));
|
||||
|
||||
if(info->errInfo->errstr != NULL)
|
||||
{
|
||||
printf(" %s", info->errInfo->errstr);
|
||||
delete(info->errInfo->errstr);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo)
|
||||
{
|
||||
s32 prio;
|
||||
static Thread thread = NULL;
|
||||
|
||||
/**
|
||||
* If music is playing, stop it. Only one playback thread should be playing
|
||||
* at any time.
|
||||
*/
|
||||
if(thread != NULL)
|
||||
{
|
||||
/* Tell the thread to stop playback before we join it */
|
||||
stopPlayback();
|
||||
|
||||
threadJoin(thread, U64_MAX);
|
||||
threadFree(thread);
|
||||
thread = NULL;
|
||||
|
||||
/* free allocated file string */
|
||||
delete(playbackInfo->file);
|
||||
}
|
||||
|
||||
if(ep_file == NULL || playbackInfo == NULL)
|
||||
return 0;
|
||||
|
||||
playbackInfo->file = strdup(ep_file);
|
||||
printf("Playing: %s\n", playbackInfo->file);
|
||||
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
thread = threadCreate(playFile, playbackInfo, 32 * 1024, prio - 1, -2, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* List current directory.
|
||||
*
|
||||
* \param from First entry in directory to list.
|
||||
* \param max Maximum number of entries to list. Must be > 0.
|
||||
* \param select File to show as selected. Must be > 0.
|
||||
* \return Number of entries listed or negative on error.
|
||||
*/
|
||||
int listDir(int from, int max, int select)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
int fileNum = 0;
|
||||
int listed = 0;
|
||||
char* wd = getcwd(NULL, 0);
|
||||
|
||||
if(wd == NULL)
|
||||
goto err;
|
||||
|
||||
consoleClear();
|
||||
printf("Dir: %.33s\n", wd);
|
||||
|
||||
if((dp = opendir(wd)) == NULL)
|
||||
goto err;
|
||||
|
||||
if(from == 0)
|
||||
{
|
||||
printf("%c../\n", select == 0 ? '>' : ' ');
|
||||
listed++;
|
||||
}
|
||||
|
||||
while((ep = readdir(dp)) != NULL)
|
||||
{
|
||||
fileNum++;
|
||||
|
||||
if(fileNum <= from)
|
||||
continue;
|
||||
|
||||
listed++;
|
||||
|
||||
printf("%c%s%.37s%s\n",
|
||||
select == fileNum ? '>' : ' ',
|
||||
ep->d_type == DT_DIR ? "\x1b[34;1m" : "",
|
||||
ep->d_name,
|
||||
ep->d_type == DT_DIR ? "/\x1b[0m" : "");
|
||||
|
||||
if(fileNum == max + from)
|
||||
break;
|
||||
}
|
||||
|
||||
if(closedir(dp) != 0)
|
||||
goto err;
|
||||
|
||||
out:
|
||||
free(wd);
|
||||
return listed;
|
||||
|
||||
err:
|
||||
listed = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of files in current working folder
|
||||
*
|
||||
* \return Number of files in current working folder, -1 on failure with
|
||||
* errno set.
|
||||
*/
|
||||
int getNumberFiles(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
int ret = 0;
|
||||
|
||||
if((dp = opendir(".")) == NULL)
|
||||
goto err;
|
||||
|
||||
while((ep = readdir(dp)) != NULL)
|
||||
ret++;
|
||||
|
||||
closedir(dp);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
err:
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#ifndef ctrmus_main_h
|
||||
#define ctrmus_main_h
|
||||
|
||||
#include "playback.h"
|
||||
|
||||
/* Default folder */
|
||||
#define DEFAULT_DIR "sdmc:/"
|
||||
|
||||
@@ -24,12 +22,15 @@ struct watchdogInfo
|
||||
struct errInfo_t* errInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows the playback thread to return any error messages that it may
|
||||
* encounter.
|
||||
*
|
||||
* \param infoIn Struct containing addresses of the event, the error code,
|
||||
* and an optional error string.
|
||||
*/
|
||||
void playbackWatchdog(void* infoIn);
|
||||
|
||||
static void showControls(void);
|
||||
|
||||
static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo);
|
||||
|
||||
/**
|
||||
* Get number of files in current working folder
|
||||
*
|
||||
@@ -38,14 +39,4 @@ static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo);
|
||||
*/
|
||||
int getNumberFiles(void);
|
||||
|
||||
/**
|
||||
* List current directory.
|
||||
*
|
||||
* \param from First entry in directory to list.
|
||||
* \param max Maximum number of entries to list. Must be > 0.
|
||||
* \param select File to show as selected. Must be > 0.
|
||||
* \return Number of entries listed or negative on error.
|
||||
*/
|
||||
int listDir(int from, int max, int select);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -71,7 +71,8 @@ uint8_t channelOpus(void)
|
||||
* Decode part of open Opus file.
|
||||
*
|
||||
* \param buffer Decoded output.
|
||||
* \return Samples read for each channel.
|
||||
* \return Samples read for each channel. 0 for end of file, negative
|
||||
* for error.
|
||||
*/
|
||||
uint64_t decodeOpus(void* buffer)
|
||||
{
|
||||
@@ -104,11 +105,7 @@ uint64_t fillOpusBuffer(OggOpusFile* opusFile, int16_t* bufferOut)
|
||||
samplesToRead > 120*48*2 ? 120*48*2 : samplesToRead);
|
||||
|
||||
if(samplesJustRead < 0)
|
||||
{
|
||||
/* TODO: Printing should not be done here. */
|
||||
printf("\nFatal error decoding Opus: %d.", samplesJustRead);
|
||||
return 0;
|
||||
}
|
||||
return samplesJustRead;
|
||||
else if(samplesJustRead == 0)
|
||||
{
|
||||
/* End of file reached. */
|
||||
|
||||
@@ -12,10 +12,118 @@
|
||||
|
||||
static volatile bool stop = false;
|
||||
|
||||
/**
|
||||
* Pause or play current file.
|
||||
*
|
||||
* \return True if paused.
|
||||
*/
|
||||
bool togglePlayback(void)
|
||||
{
|
||||
bool paused = ndspChnIsPaused(CHANNEL);
|
||||
ndspChnSetPaused(CHANNEL, !paused);
|
||||
return !paused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops current playback. Playback thread should exit as a result.
|
||||
*/
|
||||
void stopPlayback(void)
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether music is playing or paused.
|
||||
*/
|
||||
bool isPlaying(void)
|
||||
{
|
||||
return !stop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains file type.
|
||||
*
|
||||
* \param file File location.
|
||||
* \return File type, else negative and errno set.
|
||||
*/
|
||||
static int getFileType(const char *file)
|
||||
{
|
||||
FILE* ftest = fopen(file, "rb");
|
||||
int fileSig = 0;
|
||||
enum file_types file_type = FILE_TYPE_ERROR;
|
||||
|
||||
/* Failure opening file */
|
||||
if(ftest == NULL)
|
||||
return -1;
|
||||
|
||||
if(fread(&fileSig, 4, 1, ftest) == 0)
|
||||
goto err;
|
||||
|
||||
switch(fileSig)
|
||||
{
|
||||
// "RIFF"
|
||||
case 0x46464952:
|
||||
if(fseek(ftest, 4, SEEK_CUR) != 0)
|
||||
break;
|
||||
|
||||
// "WAVE"
|
||||
// Check required as AVI file format also uses "RIFF".
|
||||
if(fread(&fileSig, 4, 1, ftest) == 0)
|
||||
break;
|
||||
|
||||
if(fileSig != 0x45564157)
|
||||
break;
|
||||
|
||||
file_type = FILE_TYPE_WAV;
|
||||
break;
|
||||
|
||||
// "fLaC"
|
||||
case 0x43614c66:
|
||||
file_type = FILE_TYPE_FLAC;
|
||||
break;
|
||||
|
||||
// "OggS"
|
||||
case 0x5367674f:
|
||||
if(isOpus(file) == 0)
|
||||
file_type = FILE_TYPE_OPUS;
|
||||
else
|
||||
{
|
||||
//file_type = FILE_TYPE_OGG;
|
||||
errno = FILE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* MP3 without ID3 tag, ID3v1 tag is at the end of file, or MP3
|
||||
* with ID3 tag at the beginning of the file.
|
||||
*/
|
||||
if((fileSig << 16) == 0xFBFF0000 ||
|
||||
(fileSig << 16) == 0xFAFF0000 ||
|
||||
(fileSig << 8) == 0x33444900)
|
||||
{
|
||||
file_type = FILE_TYPE_MP3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Add this again at some point */
|
||||
//printf("Unknown magic number: %#010x\n.", fileSig);
|
||||
errno = FILE_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
err:
|
||||
fclose(ftest);
|
||||
return file_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called from a new thread only, and have only one playback
|
||||
* thread at time. This function has not been written for more than one
|
||||
* playback thread in mind.
|
||||
*
|
||||
* \param infoIn Playback information.
|
||||
*/
|
||||
void playFile(void* infoIn)
|
||||
{
|
||||
@@ -28,10 +136,6 @@ void playFile(void* infoIn)
|
||||
int ret = -1;
|
||||
const char* file = info->file;
|
||||
|
||||
|
||||
//info->errInfo->errstr = strdup("Testing.");
|
||||
//errno = 1001;
|
||||
//goto err;
|
||||
/* Reset previous stop command */
|
||||
stop = false;
|
||||
|
||||
@@ -116,7 +220,7 @@ void playFile(void* infoIn)
|
||||
{
|
||||
size_t read = (*decoder.decode)(&buffer1[0]);
|
||||
|
||||
if(read == 0)
|
||||
if(read <= 0)
|
||||
{
|
||||
lastbuf = true;
|
||||
continue;
|
||||
@@ -131,7 +235,7 @@ void playFile(void* infoIn)
|
||||
{
|
||||
size_t read = (*decoder.decode)(&buffer2[0]);
|
||||
|
||||
if(read == 0)
|
||||
if(read <= 0)
|
||||
{
|
||||
lastbuf = true;
|
||||
continue;
|
||||
@@ -157,107 +261,6 @@ out:
|
||||
|
||||
err:
|
||||
*info->errInfo->error = errno;
|
||||
printf("%s:%d errno:%d %d\n", __func__, __LINE__, errno, *info->errInfo->error);
|
||||
svcSignalEvent(*info->errInfo->failEvent);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause or play current file.
|
||||
*
|
||||
* \return True if paused.
|
||||
*/
|
||||
bool togglePlayback(void)
|
||||
{
|
||||
bool paused = ndspChnIsPaused(CHANNEL);
|
||||
ndspChnSetPaused(CHANNEL, !paused);
|
||||
return !paused;
|
||||
}
|
||||
|
||||
void stopPlayback(void)
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
|
||||
bool isPlaying(void)
|
||||
{
|
||||
return !stop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains file type.
|
||||
*
|
||||
* \param file File location.
|
||||
* \return File type, else negative and errno set.
|
||||
*/
|
||||
int getFileType(const char *file)
|
||||
{
|
||||
FILE* ftest = fopen(file, "rb");
|
||||
int fileSig = 0;
|
||||
enum file_types file_type = FILE_TYPE_ERROR;
|
||||
|
||||
/* Failure opening file */
|
||||
if(ftest == NULL)
|
||||
return -1;
|
||||
|
||||
if(fread(&fileSig, 4, 1, ftest) == 0)
|
||||
goto err;
|
||||
|
||||
switch(fileSig)
|
||||
{
|
||||
// "RIFF"
|
||||
case 0x46464952:
|
||||
if(fseek(ftest, 4, SEEK_CUR) != 0)
|
||||
break;
|
||||
|
||||
// "WAVE"
|
||||
// Check required as AVI file format also uses "RIFF".
|
||||
if(fread(&fileSig, 4, 1, ftest) == 0)
|
||||
break;
|
||||
|
||||
if(fileSig != 0x45564157)
|
||||
break;
|
||||
|
||||
file_type = FILE_TYPE_WAV;
|
||||
break;
|
||||
|
||||
// "fLaC"
|
||||
case 0x43614c66:
|
||||
file_type = FILE_TYPE_FLAC;
|
||||
break;
|
||||
|
||||
// "OggS"
|
||||
case 0x5367674f:
|
||||
if(isOpus(file) == 0)
|
||||
file_type = FILE_TYPE_OPUS;
|
||||
else
|
||||
{
|
||||
//file_type = FILE_TYPE_OGG;
|
||||
errno = FILE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* MP3 without ID3 tag, ID3v1 tag is at the end of file, or MP3
|
||||
* with ID3 tag at the beginning of the file.
|
||||
*/
|
||||
if((fileSig << 16) == 0xFBFF0000 ||
|
||||
(fileSig << 16) == 0xFAFF0000 ||
|
||||
(fileSig << 8) == 0x33444900)
|
||||
{
|
||||
file_type = FILE_TYPE_MP3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Add this again at some point */
|
||||
//printf("Unknown magic number: %#010x\n.", fileSig);
|
||||
errno = FILE_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
err:
|
||||
fclose(ftest);
|
||||
return file_type;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,13 @@ struct playbackInfo_t
|
||||
struct errInfo_t* errInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should only be called from a new thread only, and have only one playback
|
||||
* thread at time. This function has not been written for more than one
|
||||
* playback thread in mind.
|
||||
*
|
||||
* \param infoIn Playback information.
|
||||
*/
|
||||
void playFile(void* infoIn);
|
||||
|
||||
/**
|
||||
@@ -26,16 +33,14 @@ void playFile(void* infoIn);
|
||||
*/
|
||||
bool togglePlayback(void);
|
||||
|
||||
/**
|
||||
* Stops current playback. Playback thread should exit as a result.
|
||||
*/
|
||||
void stopPlayback(void);
|
||||
|
||||
/**
|
||||
* Returns whether music is playing or paused.
|
||||
*/
|
||||
bool isPlaying(void);
|
||||
|
||||
/**
|
||||
* Obtains file type.
|
||||
*
|
||||
* \param file File location.
|
||||
* \return File type, else negative.
|
||||
*/
|
||||
int getFileType(const char *file);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user