Fix Vorbis playback
Tested with a stereo OGG Vorbis file only. Signed-off-by: Mahyar Koshkouei <mk@deltabeard.com>
This commit is contained in:
@@ -26,6 +26,10 @@ char* ctrmus_strerror(int err)
|
|||||||
error = "File type is not supported";
|
error = "File type is not supported";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UNSUPPORTED_CHANNELS:
|
||||||
|
error = "Unsupported number of channels";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = strerror(err);
|
error = strerror(err);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
|
||||||
/* Errors that can't be explained with errno */
|
/* Errors that can't be explained with errno */
|
||||||
#define NDSP_INIT_FAIL 1000
|
#define NDSP_INIT_FAIL 1000
|
||||||
#define DECODER_INIT_FAIL 1001
|
#define DECODER_INIT_FAIL 1001
|
||||||
#define FILE_NOT_SUPPORTED 1002
|
#define FILE_NOT_SUPPORTED 1002
|
||||||
|
#define UNSUPPORTED_CHANNELS 1003
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct to help error handling across threads.
|
* Struct to help error handling across threads.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "mp3.h"
|
#include "mp3.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
|
||||||
static size_t* 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;
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ int getFileType(const char *file)
|
|||||||
else if(isFlac(file) == 0)
|
else if(isFlac(file) == 0)
|
||||||
file_type = FILE_TYPE_FLAC;
|
file_type = FILE_TYPE_FLAC;
|
||||||
else if(isVorbis(file) == 0)
|
else if(isVorbis(file) == 0)
|
||||||
file_type = FILE_TYPE_OGG;
|
file_type = FILE_TYPE_VORBIS;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errno = FILE_NOT_SUPPORTED;
|
errno = FILE_NOT_SUPPORTED;
|
||||||
@@ -163,8 +163,9 @@ void playFile(void* infoIn)
|
|||||||
setMp3(&decoder);
|
setMp3(&decoder);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_TYPE_OGG:
|
case FILE_TYPE_VORBIS:
|
||||||
setVorbis(&decoder);
|
setVorbis(&decoder);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto err;
|
goto err;
|
||||||
@@ -184,6 +185,12 @@ void playFile(void* infoIn)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((*decoder.channels)() > 2 || (*decoder.channels)() < 1)
|
||||||
|
{
|
||||||
|
errno = UNSUPPORTED_CHANNELS;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
buffer1 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
buffer1 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
||||||
buffer2 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
buffer2 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ enum file_types
|
|||||||
FILE_TYPE_ERROR = -1,
|
FILE_TYPE_ERROR = -1,
|
||||||
FILE_TYPE_WAV,
|
FILE_TYPE_WAV,
|
||||||
FILE_TYPE_FLAC,
|
FILE_TYPE_FLAC,
|
||||||
FILE_TYPE_OGG,
|
FILE_TYPE_VORBIS,
|
||||||
FILE_TYPE_OPUS,
|
FILE_TYPE_OPUS,
|
||||||
FILE_TYPE_MP3
|
FILE_TYPE_MP3
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
static OggVorbis_File vorbisFile;
|
static OggVorbis_File vorbisFile;
|
||||||
static vorbis_info *vi;
|
static vorbis_info *vi;
|
||||||
static int current_section;
|
|
||||||
static FILE *f;
|
static FILE *f;
|
||||||
static const size_t buffSize = 8 * 4096;
|
static const size_t buffSize = 8 * 4096;
|
||||||
|
|
||||||
@@ -36,7 +35,9 @@ void setVorbis(struct decoder_fn* decoder)
|
|||||||
int initVorbis(const char* file)
|
int initVorbis(const char* file)
|
||||||
{
|
{
|
||||||
int err = -1;
|
int err = -1;
|
||||||
f = fopen(file, "r");
|
|
||||||
|
if((f = fopen(file, "rb")) == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if(ov_open(f, &vorbisFile, NULL, 0) < 0)
|
if(ov_open(f, &vorbisFile, NULL, 0) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -44,7 +45,6 @@ int initVorbis(const char* file)
|
|||||||
if((vi = ov_info(&vorbisFile, -1)) == NULL)
|
if((vi = ov_info(&vorbisFile, -1)) == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
current_section = 0;
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -58,7 +58,6 @@ out:
|
|||||||
*/
|
*/
|
||||||
uint32_t rateVorbis(void)
|
uint32_t rateVorbis(void)
|
||||||
{
|
{
|
||||||
printf("Rate: %ld\n", vi->rate);
|
|
||||||
return vi->rate;
|
return vi->rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +68,6 @@ uint32_t rateVorbis(void)
|
|||||||
*/
|
*/
|
||||||
uint8_t channelVorbis(void)
|
uint8_t channelVorbis(void)
|
||||||
{
|
{
|
||||||
printf("Rate: %d\n", vi->channels);
|
|
||||||
return vi->channels;
|
return vi->channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +88,8 @@ uint64_t decodeVorbis(void* buffer)
|
|||||||
*/
|
*/
|
||||||
void exitVorbis(void)
|
void exitVorbis(void)
|
||||||
{
|
{
|
||||||
fclose(f);
|
|
||||||
ov_clear(&vorbisFile);
|
ov_clear(&vorbisFile);
|
||||||
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,8 +106,11 @@ uint64_t fillVorbisBuffer(char* bufferOut)
|
|||||||
|
|
||||||
while(samplesToRead > 0)
|
while(samplesToRead > 0)
|
||||||
{
|
{
|
||||||
|
static int current_section;
|
||||||
int samplesJustRead =
|
int samplesJustRead =
|
||||||
ov_read(&vorbisFile, bufferOut, samplesToRead, ¤t_section);
|
ov_read(&vorbisFile, bufferOut,
|
||||||
|
samplesToRead > 4096 ? 4096 : samplesToRead,
|
||||||
|
¤t_section);
|
||||||
|
|
||||||
if(samplesJustRead < 0)
|
if(samplesJustRead < 0)
|
||||||
return samplesJustRead;
|
return samplesJustRead;
|
||||||
@@ -119,12 +120,12 @@ uint64_t fillVorbisBuffer(char* bufferOut)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
samplesRead += samplesJustRead * 2;
|
samplesRead += samplesJustRead;
|
||||||
samplesToRead -= samplesJustRead * 2;
|
samplesToRead -= samplesJustRead;
|
||||||
bufferOut += samplesJustRead * 2;
|
bufferOut += samplesJustRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
return samplesRead;
|
return samplesRead / sizeof(int16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +136,6 @@ uint64_t fillVorbisBuffer(char* bufferOut)
|
|||||||
*/
|
*/
|
||||||
int isVorbis(const char *in)
|
int isVorbis(const char *in)
|
||||||
{
|
{
|
||||||
// TODO: Only free if a new file is selected to play.
|
|
||||||
FILE *ft = fopen(in, "r");
|
FILE *ft = fopen(in, "r");
|
||||||
OggVorbis_File testvf;
|
OggVorbis_File testvf;
|
||||||
int err;
|
int err;
|
||||||
@@ -145,7 +145,7 @@ int isVorbis(const char *in)
|
|||||||
|
|
||||||
err = ov_test(ft, &testvf, NULL, 0);
|
err = ov_test(ft, &testvf, NULL, 0);
|
||||||
|
|
||||||
fclose(ft);
|
|
||||||
ov_clear(&testvf);
|
ov_clear(&testvf);
|
||||||
|
fclose(ft);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user