Files
mice-3ds/source/m4a.c

134 lines
2.5 KiB
C

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <3ds.h>
#include "error.h"
#include "m4a.h"
#include "playback.h"
/* TODO: Integrate proper AAC decoder library (libfaad2, fdk-aac, or minimp4) */
/* For now, this is a stub implementation */
static size_t* buffSize;
static uint32_t rate = 44100;
static uint8_t channels = 2;
static int initM4a(const char* file);
static uint32_t rateM4a(void);
static uint8_t channelM4a(void);
static uint64_t decodeM4a(void* buffer);
static void exitM4a(void);
static size_t getFileSamplesM4a(void);
/**
* Set decoder parameters for M4A/AAC.
*
* \param decoder Structure to store parameters.
*/
void setM4a(struct decoder_fn* decoder)
{
decoder->init = &initM4a;
decoder->rate = &rateM4a;
decoder->channels = &channelM4a;
buffSize = &(decoder->buffSize);
decoder->decode = &decodeM4a;
decoder->exit = &exitM4a;
decoder->getFileSamples = &getFileSamplesM4a;
}
/**
* Check if a file is an M4A/AAC/ALAC file.
*
* \param file File location.
* \return 0 on success, -1 on failure.
*/
int isM4a(const char* file)
{
FILE* ftest = fopen(file, "rb");
uint32_t fileSig;
uint32_t ftypSig;
if(ftest == NULL)
return -1;
/* Read first 4 bytes (should be size of ftyp atom) */
if(fread(&fileSig, 4, 1, ftest) == 0)
{
fclose(ftest);
return -1;
}
/* Read next 4 bytes (should be 'ftyp') */
if(fread(&ftypSig, 4, 1, ftest) == 0)
{
fclose(ftest);
return -1;
}
fclose(ftest);
/* Check for 'ftyp' signature (0x70797466 in little-endian) */
if(ftypSig == 0x70797466)
return 0;
return -1;
}
static int initM4a(const char* file)
{
(void)file;
/* TODO: Initialize AAC decoder */
/* This requires:
* 1. Parse MP4 container to find AAC audio track
* 2. Extract decoder config (sample rate, channels, etc.)
* 3. Initialize AAC decoder with config
*/
/* Set default values for now */
rate = 44100;
channels = 2;
*buffSize = rate * channels * sizeof(int16_t);
errno = FILE_NOT_SUPPORTED;
return -1;
}
static uint32_t rateM4a(void)
{
return rate;
}
static uint8_t channelM4a(void)
{
return channels;
}
static uint64_t decodeM4a(void* buffer)
{
(void)buffer;
/* TODO: Decode AAC frame */
/* This requires:
* 1. Read next AAC frame from MP4 container
* 2. Decode AAC frame to PCM samples
* 3. Write PCM samples to buffer
* 4. Return number of samples decoded
*/
return 0;
}
static void exitM4a(void)
{
/* TODO: Clean up AAC decoder */
}
static size_t getFileSamplesM4a(void)
{
/* TODO: Calculate total samples from MP4 metadata */
return 0;
}