Add for audio sub-format in audion system. From Ken Pettit

This commit is contained in:
Gregory Nutt 2013-10-28 12:11:52 -06:00
parent fe0b2506dd
commit f47ca195cb
4 changed files with 160 additions and 30 deletions

View File

@ -646,7 +646,7 @@
* apps/nshlib/nsh_fscmds.c: Fix NSH listing output for the case
of a single file. Provided by Lorenz Meier (2013-9-13).
6.31 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
6.31 2013-10-28 Gregory Nutt <gnutt@nuttx.org>
* apps/nshlib/nsh_netcmds.c: Remove a warning when DHCP is not
enabled (2013-9-17).
@ -655,7 +655,7 @@
(2013-9017).
* apps/examples/ostest/Kconfig: Add configuration options for
the FPU test. There are still many OS test configuration
optionst that do not appear in Kconfig (2013-9-18).
options that do not appear in Kconfig (2013-9-18).
* apps/examples/cc3000: Condition the CC3000 example on having
selected the CC3000 device. Otherwise, you are prompted for
this the CC3000 option on each 'make oldconfig' (2013-9-18).
@ -702,4 +702,7 @@
* apps/examples/cc3000: Updates from David Sidrane (2013-10-25).
* apps/system/nxplayer: Implements a command line media
player. From Ken Pettit (2013-10-27).
* apps/system/nxplayer: Add logic to verify the audio sub-format.
From Ken Pettit (2013-10-28).
6.31 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>

View File

@ -180,6 +180,8 @@ int nxplayer_setdevice(FAR struct nxplayer_s *pPlayer, char* device);
* filename - Pointer to pathname of the file to play
* filefmt - Format of audio in filename if known, AUDIO_FMT_UNDEF
* to let nxplayer_playfile() determine automatically.
* subfmt - Sub-Format of audio in filename if known, AUDIO_FMT_UNDEF
* to let nxplayer_playfile() determine automatically.
*
* Returned values:
* OK if file found, device found, and playback started.
@ -187,7 +189,7 @@ int nxplayer_setdevice(FAR struct nxplayer_s *pPlayer, char* device);
**************************************************************************/
int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* filename,
int filefmt);
int filefmt, int subfmt);
/****************************************************************************
* Name: nxplayer_stop
@ -353,4 +355,3 @@ int nxplayer_systemreset(FAR struct nxplayer_s *pPlayer);
#endif
#endif /* __APPS_SYSTEM_NXPLAYER_NXPLAYER_H */

View File

@ -81,6 +81,7 @@ struct nxplayer_ext_fmt_s
{
const char *ext;
uint16_t format;
CODE int (*getsubformat)(FAR FILE *fd);
};
#endif
@ -88,6 +89,10 @@ struct nxplayer_ext_fmt_s
* Private Function Prototypes
****************************************************************************/
#ifdef CONFIG_AUDIO_FORMAT_MIDI
int nxplayer_getmidisubformat(FAR FILE *fd);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
@ -95,26 +100,26 @@ struct nxplayer_ext_fmt_s
#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
static const struct nxplayer_ext_fmt_s g_known_ext[] = {
#ifdef CONFIG_AUDIO_FORMAT_AC3
{ "ac3", AUDIO_FMT_AC3 },
{ "ac3", AUDIO_FMT_AC3, NULL },
#endif
#ifdef CONFIG_AUDIO_FORMAT_MP3
{ "mp3", AUDIO_FMT_MP3 },
{ "mp3", AUDIO_FMT_MP3, NULL },
#endif
#ifdef CONFIG_AUDIO_FORMAT_DTS
{ "dts", AUDIO_FMT_DTS },
{ "dts", AUDIO_FMT_DTS, NULL },
#endif
#ifdef CONFIG_AUDIO_FORMAT_WMA
{ "wma", AUDIO_FMT_WMA },
{ "wma", AUDIO_FMT_WMA, NULL },
#endif
#ifdef CONFIG_AUDIO_FORMAT_PCM
{ "wav", AUDIO_FMT_PCM },
{ "wav", AUDIO_FMT_PCM, NULL },
#endif
#ifdef CONFIG_AUDIO_FORMAT_MIDI
{ "mid", AUDIO_FMT_MIDI },
{ "midi", AUDIO_FMT_MIDI },
{ "mid", AUDIO_FMT_MIDI, nxplayer_getmidisubformat },
{ "midi", AUDIO_FMT_MIDI, nxplayer_getmidisubformat },
#endif
#ifdef CONFIG_AUDIO_FORMAT_OGG_VORBIS
{ "ogg", AUDIO_FMT_OGG_VORBIS }
{ "ogg", AUDIO_FMT_OGG_VORBIS, NULL }
#endif
};
static const int g_known_ext_count = sizeof(g_known_ext) /
@ -140,12 +145,15 @@ static const int g_known_ext_count = sizeof(g_known_ext) /
*
****************************************************************************/
static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format)
static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format,
int subfmt)
{
struct dirent* pDevice;
DIR* dirp;
DIR* dirp;
char path[64];
struct audio_caps_s caps;
uint8_t supported = TRUE;
uint8_t x;
/* If we have a preferred device, then open it */
@ -156,7 +164,7 @@ static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format)
* format is specified by the device
*/
if (((pPlayer->prefformat & format) == 0) ||
if (((pPlayer->prefformat & (1 << (format - 1)) == 0) ||
((pPlayer->preftype & AUDIO_TYPE_OUTPUT) == 0))
{
/* Format not supported by the device */
@ -223,19 +231,69 @@ static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format)
caps.ac_len = sizeof(caps);
caps.ac_type = AUDIO_TYPE_QUERY;
caps.ac_subtype = AUDIO_TYPE_QUERY;
if (ioctl(pPlayer->devFd, AUDIOIOC_GETCAPS, (unsigned long) &caps)
== caps.ac_len)
{
/* Test if this device supports the format we want */
int ac_format = caps.ac_format[0] | (caps.ac_format[1] << 8);
if (((ac_format & format) != 0) &&
if (((ac_format & (1 << (format - 1))) != 0) &&
(caps.ac_controls[0] & AUDIO_TYPE_OUTPUT))
{
/* Yes, it supports this format. Use this device */
/* Do subformat detection */
closedir(dirp);
return OK;
if (subfmt != AUDIO_FMT_UNDEF)
{
/* Prepare to get sub-formats for this main format */
caps.ac_subtype = format;
caps.ac_format[0] = 0;
while (ioctl(pPlayer->devFd, AUDIOIOC_GETCAPS,
(unsigned long) &caps) == caps.ac_len)
{
/* Check the next set of 4 controls to find the subformat */
for (x = 0; x < sizeof(caps.ac_controls); x++)
{
if (caps.ac_controls[x] == subfmt)
{
/* Sub format supported! */
break;
}
else if (caps.ac_controls[x] == AUDIO_SUBFMT_END)
{
/* Sub format not supported */
supported = FALSE;
break;
}
}
/* If we reached the end of the subformat list, then
* break out of the loop.
*/
if (x != sizeof(caps.ac_controls))
{
break;
}
/* Increment ac_format[0] to get next set of subformats */
caps.ac_format[0]++;
}
}
/* Test if subformat needed and detected */
if (supported)
{
/* Yes, it supports this format. Use this device */
closedir(dirp);
return OK;
}
}
}
@ -257,6 +315,47 @@ static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format)
return -ENODEV;
}
/****************************************************************************
* Name: nxplayer_getmidisubformat
*
* nxplayer_getmidisubformat() reads the MIDI header and determins the
* MIDI format of the file.
*
****************************************************************************/
#ifdef CONFIG_AUDIO_FORMAT_MIDI
int nxplayer_getmidisubformat(FAR FILE *fd)
{
char type[2];
int ret;
/* Seek to location 8 in the file (the format type) */
fseek(fd, 8, SEEK_SET);
fread(type, 1, 2, fd);
/* Set return value based on type */
switch (type[1])
{
case 0:
ret = AUDIO_SUBFMT_MIDI_0;
break;
case 1:
ret = AUDIO_SUBFMT_MIDI_1;
break;
case 2:
ret = AUDIO_SUBFMT_MIDI_2;
break;
}
fseek(fd, 0, SEEK_SET);
return ret;
}
#endif
/****************************************************************************
* Name: nxplayer_fmtfromextension
*
@ -266,10 +365,12 @@ static int nxplayer_opendevice(FAR struct nxplayer_s *pPlayer, int format)
****************************************************************************/
#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
static int nxplayer_fmtfromextension(char* pFilename)
static inline int nxplayer_fmtfromextension(FAR struct nxplayer_s *pPlayer,
char* pFilename, int *subfmt)
{
const char *pExt;
int x, c;
const char *pExt;
uint8_t x;
uint8_t c;
/* Find the file extension, if any */
@ -289,6 +390,14 @@ static int nxplayer_fmtfromextension(char* pFilename)
if (strcasecmp(pExt, g_known_ext[c].ext) == 0)
{
/* Test if we have a sub-format detection routine */
if (subfmt && g_known_ext[c].getsubformat)
{
*subfmt = g_known_ext[c].getsubformat(pPlayer->fileFd);
}
/* Return the format for this extension */
return g_known_ext[c].format;
@ -1027,6 +1136,7 @@ int nxplayer_stop(FAR struct nxplayer_s *pPlayer)
sem_post(&pPlayer->sem); /* Release the semaphore */
return OK;
}
sem_post(&pPlayer->sem);
/* Notify the playback thread that it needs to cancel the playback */
@ -1067,9 +1177,10 @@ int nxplayer_stop(FAR struct nxplayer_s *pPlayer)
*
****************************************************************************/
int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filefmt)
int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filefmt,
int subfmt)
{
int ret;
int ret, tmpsubfmt = AUDIO_FMT_UNDEF;
struct mq_attr attr;
struct sched_param sparam;
pthread_attr_t tattr;
@ -1106,7 +1217,9 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filef
/* File not found in the media dir. Do a search */
if (nxplayer_mediasearch(pPlayer, pFilename, path, sizeof(path)) != OK)
return -ENOENT;
{
return -ENOENT;
}
#else
return -ENOENT;
#endif /* CONFIG_NXPLAYER_MEDIA_SEARCH */
@ -1121,14 +1234,14 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filef
#ifdef CONFIG_NXPLAYER_FMT_FROM_EXT
if (filefmt == AUDIO_FMT_UNDEF)
filefmt = nxplayer_fmtfromextension(pFilename);
filefmt = nxplayer_fmtfromextension(pPlayer, pFilename, &tmpsubfmt);
#endif
/* If type not identified, then test for known header types */
#ifdef CONFIG_NXPLAYER_FMT_FROM_HEADER
if (filefmt == AUDIO_FMT_UNDEF)
filefmt = nxplayer_fmtfromheader(pPlayer);
filefmt = nxplayer_fmtfromheader(pPlayer, &subfmt, &tmpsubfmt);
#endif
/* Test if we determined the file format */
@ -1141,9 +1254,16 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filef
goto err_out_nodev;
}
/* Test if we have a sub format assignment from above */
if (subfmt == AUDIO_FMT_UNDEF)
{
subfmt = tmpsubfmt;
}
/* Try to open the device */
ret = nxplayer_opendevice(pPlayer, filefmt);
ret = nxplayer_opendevice(pPlayer, filefmt, subfmt);
if (ret < 0)
{
/* Error opening the device */
@ -1224,12 +1344,14 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer, char* pFilename, int filef
err_out:
close(pPlayer->devFd);
pPlayer->devFd = -1;
err_out_nodev:
if (pPlayer->fileFd != NULL)
{
fclose(pPlayer->fileFd);
pPlayer->fileFd = NULL;
}
return ret;
}

View File

@ -187,7 +187,7 @@ static int nxplayer_cmd_play(FAR struct nxplayer_s *pPlayer, char* parg)
/* Try to play the file specified */
ret = nxplayer_playfile(pPlayer, parg, AUDIO_FMT_UNDEF);
ret = nxplayer_playfile(pPlayer, parg, AUDIO_FMT_UNDEF, AUDIO_FMT_UNDEF);
/* Test if the device file exists */
@ -507,7 +507,11 @@ static int nxplayer_cmd_device(FAR struct nxplayer_s *pPlayer, char* parg)
static int nxplayer_cmd_quit(FAR struct nxplayer_s *pPlayer, char* parg)
{
/* Nothing to do */
/* Stop the playback if any */
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
nxplayer_stop(pPlayer);
#endif
return OK;
}