Merge branch 'errHandling'
This commit is contained in:
2
Makefile
2
Makefile
@@ -51,7 +51,7 @@ EXTRA_OUTPUT_FILES :=
|
|||||||
LIBRARY_DIRS := $(DEVKITPRO)/libctru $(DEVKITPRO)/portlibs/armv6k
|
LIBRARY_DIRS := $(DEVKITPRO)/libctru $(DEVKITPRO)/portlibs/armv6k
|
||||||
LIBRARIES := mpg123 opusfile opus ogg ctru m
|
LIBRARIES := mpg123 opusfile opus ogg ctru m
|
||||||
|
|
||||||
BUILD_FLAGS :=
|
BUILD_FLAGS := -Wall -Wextra
|
||||||
RUN_FLAGS :=
|
RUN_FLAGS :=
|
||||||
|
|
||||||
VERSION_PARTS := $(subst ., ,$(shell git describe --tags --abbrev=0))
|
VERSION_PARTS := $(subst ., ,$(shell git describe --tags --abbrev=0))
|
||||||
|
|||||||
13
source/all.h
13
source/all.h
@@ -1,9 +1,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Channel to play music on */
|
|
||||||
#define CHANNEL 0x08
|
|
||||||
|
|
||||||
/* Adds extra debugging text */
|
/* Adds extra debugging text */
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
@@ -14,13 +11,3 @@
|
|||||||
|
|
||||||
#define delete(ptr) \
|
#define delete(ptr) \
|
||||||
free((void*) ptr); ptr = NULL
|
free((void*) ptr); ptr = NULL
|
||||||
|
|
||||||
struct decoder_fn
|
|
||||||
{
|
|
||||||
int (* init)(const char* file);
|
|
||||||
uint32_t (* rate)(void);
|
|
||||||
uint8_t (* channels)(void);
|
|
||||||
int buffSize;
|
|
||||||
uint64_t (* decode)(void*);
|
|
||||||
void (* exit)(void);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
#define DR_FLAC_IMPLEMENTATION
|
#define DR_FLAC_IMPLEMENTATION
|
||||||
#include <./dr_libs/dr_flac.h>
|
#include <./dr_libs/dr_flac.h>
|
||||||
|
|
||||||
#include "all.h"
|
|
||||||
#include "flac.h"
|
#include "flac.h"
|
||||||
|
#include "playback.h"
|
||||||
|
|
||||||
static drflac* pFlac;
|
static drflac* pFlac;
|
||||||
static const int buffSize = 16 * 1024;
|
static const size_t buffSize = 16 * 1024;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set decoder parameters for flac.
|
* Set decoder parameters for flac.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include "playback.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set decoder parameters for flac.
|
* Set decoder parameters for flac.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ static void showControls(void)
|
|||||||
"Stop: L+B\n"
|
"Stop: L+B\n"
|
||||||
"A: Open File\n"
|
"A: Open File\n"
|
||||||
"B: Go up folder\n"
|
"B: Go up folder\n"
|
||||||
"Start: Exit\n");
|
"Start: Exit\n"
|
||||||
|
"Browse: Up, Down, Left or Right\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,6 +83,13 @@ static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo)
|
|||||||
s32 prio;
|
s32 prio;
|
||||||
static Thread thread = NULL;
|
static Thread thread = NULL;
|
||||||
|
|
||||||
|
if(ep_file != NULL && getFileType(ep_file) == FILE_TYPE_ERROR)
|
||||||
|
{
|
||||||
|
*playbackInfo->errInfo->error = errno;
|
||||||
|
svcSignalEvent(*playbackInfo->errInfo->failEvent);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If music is playing, stop it. Only one playback thread should be playing
|
* If music is playing, stop it. Only one playback thread should be playing
|
||||||
* at any time.
|
* at any time.
|
||||||
@@ -94,9 +102,6 @@ static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo)
|
|||||||
threadJoin(thread, U64_MAX);
|
threadJoin(thread, U64_MAX);
|
||||||
threadFree(thread);
|
threadFree(thread);
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
/* free allocated file string */
|
|
||||||
delete(playbackInfo->file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ep_file == NULL || playbackInfo == NULL)
|
if(ep_file == NULL || playbackInfo == NULL)
|
||||||
@@ -256,12 +261,11 @@ int main(int argc, char **argv)
|
|||||||
u32 kHeld;
|
u32 kHeld;
|
||||||
static u64 mill = 0;
|
static u64 mill = 0;
|
||||||
|
|
||||||
hidScanInput();
|
|
||||||
|
|
||||||
gfxSwapBuffers();
|
|
||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
gspWaitForVBlank();
|
gspWaitForVBlank();
|
||||||
|
gfxSwapBuffers();
|
||||||
|
|
||||||
|
hidScanInput();
|
||||||
kDown = hidKeysDown();
|
kDown = hidKeysDown();
|
||||||
kHeld = hidKeysHeld();
|
kHeld = hidKeysHeld();
|
||||||
|
|
||||||
@@ -343,6 +347,52 @@ int main(int argc, char **argv)
|
|||||||
err_print("Unable to list directory.");
|
err_print("Unable to list directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((kDown & KEY_LEFT ||
|
||||||
|
((kHeld & KEY_LEFT) && (osGetTime() - mill > 500))) &&
|
||||||
|
fileNum > 0)
|
||||||
|
{
|
||||||
|
int skip = MAX_LIST / 2;
|
||||||
|
|
||||||
|
if(fileNum < skip)
|
||||||
|
skip = fileNum;
|
||||||
|
|
||||||
|
fileNum -= skip;
|
||||||
|
|
||||||
|
/* 26 is the maximum number of entries that can be printed */
|
||||||
|
if(fileMax - fileNum > 26 && from != 0)
|
||||||
|
{
|
||||||
|
from -= skip;
|
||||||
|
if(from < 0)
|
||||||
|
from = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listDir(from, MAX_LIST, fileNum) < 0)
|
||||||
|
err_print("Unable to list directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if((kDown & KEY_RIGHT ||
|
||||||
|
((kHeld & KEY_RIGHT) && (osGetTime() - mill > 500))) &&
|
||||||
|
fileNum < fileMax)
|
||||||
|
{
|
||||||
|
int skip = fileMax - fileNum;
|
||||||
|
|
||||||
|
if(skip > MAX_LIST / 2)
|
||||||
|
skip = MAX_LIST / 2;
|
||||||
|
|
||||||
|
fileNum += skip;
|
||||||
|
|
||||||
|
if(fileNum >= MAX_LIST && fileMax - fileNum >= 0 &&
|
||||||
|
from < fileMax - MAX_LIST)
|
||||||
|
{
|
||||||
|
from += skip;
|
||||||
|
if(from > fileMax - MAX_LIST)
|
||||||
|
from = fileMax - MAX_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listDir(from, MAX_LIST, fileNum) < 0)
|
||||||
|
err_print("Unable to list directory.");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pressing B goes up a folder, as well as pressing A or R when ".."
|
* Pressing B goes up a folder, as well as pressing A or R when ".."
|
||||||
* is selected.
|
* is selected.
|
||||||
@@ -350,8 +400,7 @@ int main(int argc, char **argv)
|
|||||||
if((kDown & KEY_B) ||
|
if((kDown & KEY_B) ||
|
||||||
((kDown & KEY_A) && (from == 0 && fileNum == 0)))
|
((kDown & KEY_A) && (from == 0 && fileNum == 0)))
|
||||||
{
|
{
|
||||||
if(chdir("..") != 0)
|
chdir("..");
|
||||||
err_print("chdir");
|
|
||||||
|
|
||||||
fileNum = 0;
|
fileNum = 0;
|
||||||
from = 0;
|
from = 0;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "all.h"
|
|
||||||
#include "mp3.h"
|
#include "mp3.h"
|
||||||
|
#include "playback.h"
|
||||||
|
|
||||||
static int* buffSize;
|
static size_t* buffSize;
|
||||||
static mpg123_handle *mh = NULL;
|
static mpg123_handle *mh = NULL;
|
||||||
static uint32_t rate;
|
static uint32_t rate;
|
||||||
static uint8_t channels;
|
static uint8_t channels;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include "playback.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set decoder parameters for MP3.
|
* Set decoder parameters for MP3.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "all.h"
|
|
||||||
#include "opus.h"
|
#include "opus.h"
|
||||||
|
#include "playback.h"
|
||||||
|
|
||||||
static OggOpusFile* opusFile;
|
static OggOpusFile* opusFile;
|
||||||
static const OpusHead* opusHead;
|
static const OpusHead* opusHead;
|
||||||
static const int buffSize = 32 * 1024;
|
static const size_t buffSize = 32 * 1024;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set decoder parameters for Opus.
|
* Set decoder parameters for Opus.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <opus/opusfile.h>
|
#include <opus/opusfile.h>
|
||||||
|
#include "playback.h"
|
||||||
|
|
||||||
void setOpus(struct decoder_fn* decoder);
|
void setOpus(struct decoder_fn* decoder);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -46,10 +47,10 @@ bool isPlaying(void)
|
|||||||
* \param file File location.
|
* \param file File location.
|
||||||
* \return File type, else negative and errno set.
|
* \return File type, else negative and errno set.
|
||||||
*/
|
*/
|
||||||
static int getFileType(const char *file)
|
int getFileType(const char *file)
|
||||||
{
|
{
|
||||||
FILE* ftest = fopen(file, "rb");
|
FILE* ftest = fopen(file, "rb");
|
||||||
int fileSig = 0;
|
uint32_t fileSig;
|
||||||
enum file_types file_type = FILE_TYPE_ERROR;
|
enum file_types file_type = FILE_TYPE_ERROR;
|
||||||
|
|
||||||
/* Failure opening file */
|
/* Failure opening file */
|
||||||
@@ -83,7 +84,7 @@ static int getFileType(const char *file)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// "OggS"
|
// "OggS"
|
||||||
case 0x5367674f:
|
case 0x5367674F:
|
||||||
if(isOpus(file) == 0)
|
if(isOpus(file) == 0)
|
||||||
file_type = FILE_TYPE_OPUS;
|
file_type = FILE_TYPE_OPUS;
|
||||||
else
|
else
|
||||||
@@ -135,6 +136,7 @@ void playFile(void* infoIn)
|
|||||||
bool lastbuf = false;
|
bool lastbuf = false;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
const char* file = info->file;
|
const char* file = info->file;
|
||||||
|
bool isNdspInit = false;
|
||||||
|
|
||||||
/* Reset previous stop command */
|
/* Reset previous stop command */
|
||||||
stop = false;
|
stop = false;
|
||||||
@@ -161,12 +163,14 @@ void playFile(void* infoIn)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(R_FAILED(ndspInit()))
|
if(ndspInit() < 0)
|
||||||
{
|
{
|
||||||
errno = NDSP_INIT_FAIL;
|
errno = NDSP_INIT_FAIL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isNdspInit = true;
|
||||||
|
|
||||||
if((ret = (*decoder.init)(file)) != 0)
|
if((ret = (*decoder.init)(file)) != 0)
|
||||||
{
|
{
|
||||||
errno = DECODER_INIT_FAIL;
|
errno = DECODER_INIT_FAIL;
|
||||||
@@ -202,10 +206,6 @@ void playFile(void* infoIn)
|
|||||||
|
|
||||||
while(stop == false)
|
while(stop == false)
|
||||||
{
|
{
|
||||||
gfxSwapBuffers();
|
|
||||||
gfxFlushBuffers();
|
|
||||||
gspWaitForVBlank();
|
|
||||||
|
|
||||||
svcSleepThread(100 * 1000);
|
svcSleepThread(100 * 1000);
|
||||||
|
|
||||||
/* When the last buffer has finished playing, break. */
|
/* When the last buffer has finished playing, break. */
|
||||||
@@ -252,8 +252,13 @@ void playFile(void* infoIn)
|
|||||||
|
|
||||||
(*decoder.exit)();
|
(*decoder.exit)();
|
||||||
out:
|
out:
|
||||||
ndspChnWaveBufClear(CHANNEL);
|
if(isNdspInit == true)
|
||||||
ndspExit();
|
{
|
||||||
|
ndspChnWaveBufClear(CHANNEL);
|
||||||
|
ndspExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(info->file);
|
||||||
linearFree(buffer1);
|
linearFree(buffer1);
|
||||||
linearFree(buffer2);
|
linearFree(buffer2);
|
||||||
threadExit(0);
|
threadExit(0);
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#ifndef ctrmus_playback_h
|
#ifndef ctrmus_playback_h
|
||||||
#define ctrmus_playback_h
|
#define ctrmus_playback_h
|
||||||
|
|
||||||
|
/* Channel to play music on */
|
||||||
|
#define CHANNEL 0x08
|
||||||
|
|
||||||
enum file_types
|
enum file_types
|
||||||
{
|
{
|
||||||
FILE_TYPE_ERROR = -1,
|
FILE_TYPE_ERROR = -1,
|
||||||
@@ -11,21 +14,22 @@ enum file_types
|
|||||||
FILE_TYPE_MP3
|
FILE_TYPE_MP3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct decoder_fn
|
||||||
|
{
|
||||||
|
int (* init)(const char* file);
|
||||||
|
uint32_t (* rate)(void);
|
||||||
|
uint8_t (* channels)(void);
|
||||||
|
size_t buffSize;
|
||||||
|
uint64_t (* decode)(void*);
|
||||||
|
void (* exit)(void);
|
||||||
|
};
|
||||||
|
|
||||||
struct playbackInfo_t
|
struct playbackInfo_t
|
||||||
{
|
{
|
||||||
char* file;
|
char* file;
|
||||||
struct errInfo_t* errInfo;
|
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause or play current file.
|
* Pause or play current file.
|
||||||
*
|
*
|
||||||
@@ -43,4 +47,21 @@ void stopPlayback(void);
|
|||||||
*/
|
*/
|
||||||
bool isPlaying(void);
|
bool isPlaying(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains file type.
|
||||||
|
*
|
||||||
|
* \param file File location.
|
||||||
|
* \return File type, else negative and errno set.
|
||||||
|
*/
|
||||||
|
int getFileType(const char *file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "all.h"
|
|
||||||
#include "wav.h"
|
#include "wav.h"
|
||||||
|
#include "playback.h"
|
||||||
|
|
||||||
static const int buffSize = 16 * 1024;
|
static const size_t buffSize = 16 * 1024;
|
||||||
static FILE* pWav = NULL;
|
static FILE* pWav = NULL;
|
||||||
static char header[45];
|
static char header[45];
|
||||||
static uint8_t channels;
|
static uint8_t channels;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include "playback.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set decoder parameters for WAV.
|
* Set decoder parameters for WAV.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user