Add audio lineout controls (play, pause, volume control)

This commit is contained in:
rocky
2005-03-01 00:41:34 +00:00
parent 53916b41bf
commit 47a5589e61
7 changed files with 240 additions and 67 deletions

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.22 2005/02/13 00:20:04 rocky Exp $ # $Id: Makefile.am,v 1.23 2005/03/01 00:41:34 rocky Exp $
# #
# Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> # Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
# #
@@ -23,6 +23,7 @@
libcdioincludedir=$(includedir)/cdio libcdioincludedir=$(includedir)/cdio
libcdioinclude_HEADERS = \ libcdioinclude_HEADERS = \
audio.h \
bytesex.h \ bytesex.h \
bytesex_asm.h \ bytesex_asm.h \
paranoia.h \ paranoia.h \

129
include/cdio/audio.h Normal file
View File

@@ -0,0 +1,129 @@
/* -*- c -*-
$Id: audio.h,v 1.1 2005/03/01 00:41:34 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file audio.h
*
* \brief The top-level header for CD audio-related libcdio
* calls. These control playing of the CD-ROM through its
* line-out jack.
*/
#ifndef __CDIO_AUDIO_H__
#define __CDIO_AUDIO_H__
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! This struct is used by the cdio_audio_read_subchannel */
typedef struct cdio_subchannel_s
{
uint8_t cdsc_format;
uint8_t cdsc_audiostatus;
uint8_t cdsc_adr: 4;
uint8_t cdsc_ctrl: 4;
uint8_t cdsc_trk;
uint8_t cdsc_ind;
union cdio_cdrom_addr cdsc_absaddr;
union cdio_cdrom_addr cdsc_reladdr;
} cdio_subchannel_t;
/*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
typedef struct cdio_audio_volume_s
{
uint8_t channel0;
uint8_t channel1;
uint8_t channel2;
uint8_t channel3;
} cdio_audio_volume_t;
/* This struct is used by the CDROMPLAYTRKIND ioctl */
typedef struct cdio_track_index_s
{
uint8_t i_start_track; /* start track */
uint8_t i_start_index; /* start index */
uint8_t i_end_track; /* end track */
uint8_t i_end_index; /* end index */
} cdio_track_index_t;
/*!
Get volume of an audio CD.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/
cdio_audio_volume_t *p_volume);
/*!
Pause playing CD through analog output
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_pause (CdIo_t *p_cdio);
/*!
Playing CD through analog output at the given MSF.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio, msf_t *p_msf);
/*!
Playing CD through analog output at the desired track and index
@param p_cdio the CD object to be acted upon.
@param p_track_index location to start/end.
*/
driver_return_code_t cdio_audio_play_track_index
( CdIo_t *p_cdio, cdio_track_index_t *p_track_index);
/*!
Get subchannel information.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio,
cdio_subchannel_t *p_subchannel);
/*!
Resume playing an audio CD.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_resume (CdIo_t *p_cdio);
/*!
Set volume of an audio CD.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_set_volume (CdIo_t *p_cdio, const
cdio_audio_volume_t *p_volume);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_AUDIO_H__ */

View File

@@ -1,5 +1,5 @@
/* /*
$Id: mmc.h,v 1.12 2005/02/19 11:45:03 rocky Exp $ $Id: mmc.h,v 1.13 2005/03/01 00:41:34 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -146,6 +146,20 @@ typedef enum {
} cdio_mmc_gpcmd_t; } cdio_mmc_gpcmd_t;
/** Read Subchannel states */
typedef enum {
CDIO_MMC_READ_SUB_ST_INVALID = 0x00, /**< audio status not supported */
CDIO_MMC_READ_SUB_ST_PLAY = 0x11, /**< audio play operation in
progress */
CDIO_MMC_READ_SUB_ST_PAUSED = 0x12, /**< audio play operation paused */
CDIO_MMC_READ_SUB_ST_COMPLETED = 0x13, /**< audio play successfully
completed */
CDIO_MMC_READ_SUB_ST_ERROR = 0x14, /**< audio play stopped due to
error */
CDIO_MMC_READ_SUB_ST_NO_STATUS = 0x15, /**< no current audio status to
return */
} cdio_mmc_read_sub_state_t;
/*! Level values that can go into READ_CD */ /*! Level values that can go into READ_CD */
#define CDIO_MMC_READ_TYPE_ANY 0 /**< All types */ #define CDIO_MMC_READ_TYPE_ANY 0 /**< All types */
#define CDIO_MMC_READ_TYPE_CDDA 1 /**< Only CD-DA sectors */ #define CDIO_MMC_READ_TYPE_CDDA 1 /**< Only CD-DA sectors */

View File

@@ -1,5 +1,5 @@
/* /*
$Id: types.h,v 1.26 2005/02/10 01:59:06 rocky Exp $ $Id: types.h,v 1.27 2005/03/01 00:41:34 rocky Exp $
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -183,12 +183,12 @@ extern "C" {
@see lba_t @see lba_t
*/ */
PRAGMA_BEGIN_PACKED PRAGMA_BEGIN_PACKED
struct msf_rec { struct msf_s {
uint8_t m, s, f; uint8_t m, s, f;
} GNUC_PACKED; } GNUC_PACKED;
PRAGMA_END_PACKED PRAGMA_END_PACKED
typedef struct msf_rec msf_t; typedef struct msf_s msf_t;
#define msf_t_SIZEOF 3 #define msf_t_SIZEOF 3
@@ -217,13 +217,20 @@ extern "C" {
*/ */
typedef int32_t lba_t; typedef int32_t lba_t;
/*! The type of a Logical Sector Number. Note that an lba lsn be negative /*! The type of a Logical Sector Number. Note that an lba can be negative
and the MMC3 specs allow for a conversion of a negative lba and the MMC3 specs allow for a conversion of a negative lba.
@see msf_t @see msf_t
*/ */
typedef int32_t lsn_t; typedef int32_t lsn_t;
/* Address in either MSF or logical format */
union cdio_cdrom_addr
{
msf_t msf;
lba_t lba;
};
/*! The type of a track number 0..99. */ /*! The type of a track number 0..99. */
typedef uint8_t track_t; typedef uint8_t track_t;

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.7 2005/02/05 13:07:02 rocky Exp $ # $Id: Makefile.am,v 1.8 2005/03/01 00:41:34 rocky Exp $
# #
# Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> # Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
# #
@@ -62,6 +62,7 @@ libcdio_sources = \
_cdio_stream.c \ _cdio_stream.c \
_cdio_stream.h \ _cdio_stream.h \
_cdio_sunos.c \ _cdio_sunos.c \
audio.c \
cd_types.c \ cd_types.c \
cdio.c \ cdio.c \
cdtext.c \ cdtext.c \

View File

@@ -1,5 +1,5 @@
/* /*
$Id: _cdio_linux.c,v 1.28 2005/02/28 04:05:17 rocky Exp $ $Id: _cdio_linux.c,v 1.29 2005/03/01 00:41:34 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h" # include "config.h"
#endif #endif
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.28 2005/02/28 04:05:17 rocky Exp $"; static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.29 2005/03/01 00:41:34 rocky Exp $";
#include <string.h> #include <string.h>
@@ -648,42 +648,6 @@ read_audio_sectors_linux (void *p_user_data, void *p_buf, lsn_t i_lsn,
CDIO_MMC_READ_TYPE_CDDA, i_blocks); CDIO_MMC_READ_TYPE_CDDA, i_blocks);
} }
#if 0
/* MMC driver to read audio sectors.
Can read only up to 25 blocks.
*/
static driver_return_code_t
read_data_sectors_linux (void *p_user_data, void *p_buf, lsn_t i_lsn,
uint16_t i_blocksize, uint32_t i_blocks)
{
_img_private_t *p_env = p_user_data;
if (ISO_BLOCKSIZE == i_blocksize) {
msf_t msf;
struct cdrom_msf0 linux_msf;
int i_rc;
cdio_lsn_to_msf(i_lsn, &msf);
linux_msf.minute = msf.m;
linux_msf.second = msf.s;
linux_msf.frame = msf.f;
i_rc = ioctl(p_env->gen.fd, CDROMSEEK, &linux_msf);
// cdio_warn("%s: %s\n",
// "error in ioctl CDROMREADTOCHDR", strerror(errno));
if (0 == i_rc) {
unsigned int j = 0;
for (j=0; j<i_blocks; j++) {
void *p_buf2 = ((char *)p_buf ) + (j * ISO_BLOCKSIZE);
if (0 != ioctl(p_env->gen.fd, CDROMREADCOOKED, p_buf2))
break;
}
if (j==i_blocks) return DRIVER_OP_SUCCESS;
}
}
return read_data_sectors_mmc( p_env->gen.cdio, p_buf, i_lsn, i_blocksize,
i_blocks );
}
#endif
/* Packet driver to read mode2 sectors. /* Packet driver to read mode2 sectors.
Can read only up to 25 blocks. Can read only up to 25 blocks.
*/ */
@@ -1318,8 +1282,8 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
.lseek = cdio_generic_lseek, .lseek = cdio_generic_lseek,
.read = cdio_generic_read, .read = cdio_generic_read,
.read_audio_sectors = read_audio_sectors_linux, .read_audio_sectors = read_audio_sectors_linux,
#if 0 #if 1
.read_data_sectors = read_data_sectors_linux, .read_data_sectors = read_data_sectors_generic,
#else #else
.read_data_sectors = read_data_sectors_mmc, .read_data_sectors = read_data_sectors_mmc,
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdio_private.h,v 1.16 2005/02/17 07:03:37 rocky Exp $ $Id: cdio_private.h,v 1.17 2005/03/01 00:41:34 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -29,6 +29,7 @@
#endif #endif
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/audio.h>
#include <cdio/cdtext.h> #include <cdio/cdtext.h>
#include "mmc_private.h" #include "mmc_private.h"
@@ -53,12 +54,67 @@ extern "C" {
typedef struct { typedef struct {
/*!
Get volume of an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_get_volume)
(void *p_env, /*out*/ cdio_audio_volume_t *p_volume);
/*!
Pause playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_pause) (void *p_env);
/*!
Playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_play_msf) ( void *p_env, msf_t *p_msf );
/*!
Playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_play_track_index)
( void *p_env, cdio_track_index_t *p_track_index );
/*!
Get subchannel information.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_read_subchannel)
( void *p_env, cdio_subchannel_t *subchannel );
/*!
Resume playing an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_resume) ( void *p_env );
/*!
Set volume of an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_set_volume)
( void *p_env, const cdio_audio_volume_t *p_volume );
/*! /*!
Eject media in CD drive. If successful, as a side effect we Eject media in CD drive. If successful, as a side effect we
also free obj. Return 0 if success and 1 for failure. also free obj. Return 0 if success and 1 for failure.
@param p_cdio the CD object to be acted upon. @param p_env the CD object to be acted upon.
If the CD is ejected *p_cdio is freed and p_cdio set to NULL. If the CD is ejected *p_env is freed and p_env set to NULL.
*/ */
int (*eject_media) (void *p_env); int (*eject_media) (void *p_env);
@@ -141,8 +197,8 @@ extern "C" {
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
False is returned if we had an error getting the information. False is returned if we had an error getting the information.
*/ */
bool (*get_hwinfo) ( const CdIo_t *p_cdio, bool (*get_hwinfo)
/* out*/ cdio_hwinfo_t *p_hw_info ); ( const CdIo_t *p_cdio, /* out*/ cdio_hwinfo_t *p_hw_info );
/*! /*!
Find out if media has changed since the last call. Find out if media has changed since the last call.
@@ -213,8 +269,8 @@ extern "C" {
or -2 if not implimented (yet). Is this meaningful if not an or -2 if not implimented (yet). Is this meaningful if not an
audio track? audio track?
*/ */
track_flag_t (*get_track_preemphasis) (const void *p_env, track_flag_t (*get_track_preemphasis)
track_t i_track); ( const void *p_env, track_t i_track );
/*! /*!
lseek - reposition read/write file offset lseek - reposition read/write file offset
@@ -254,40 +310,41 @@ extern "C" {
@param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE, @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf. M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf.
*/ */
driver_return_code_t (*read_data_sectors) (void *p_env, void *p_buf, driver_return_code_t (*read_data_sectors)
lsn_t i_lsn, ( void *p_env, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize,
uint16_t i_blocksize, uint32_t i_blocks );
uint32_t i_blocks);
/*! /*!
Reads a single mode2 sector from cd device into buf starting Reads a single mode2 sector from cd device into buf starting
from lsn. Returns 0 if no error. from lsn. Returns 0 if no error.
*/ */
int (*read_mode2_sector) (void *p_env, void *p_buf, lsn_t i_lsn, int (*read_mode2_sector)
bool b_mode2_form2); ( void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2 );
/*! /*!
Reads i_blocks of mode2 sectors from cd device into data starting Reads i_blocks of mode2 sectors from cd device into data starting
from lsn. from lsn.
Returns 0 if no error. Returns 0 if no error.
*/ */
int (*read_mode2_sectors) (void *p_env, void *p_buf, lsn_t i_lsn, int (*read_mode2_sectors)
bool b_mode2_form2, unsigned int i_blocks); ( void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2,
unsigned int i_blocks );
/*! /*!
Reads a single mode1 sector from cd device into buf starting Reads a single mode1 sector from cd device into buf starting
from lsn. Returns 0 if no error. from lsn. Returns 0 if no error.
*/ */
int (*read_mode1_sector) (void *p_env, void *p_buf, lsn_t i_lsn, int (*read_mode1_sector)
bool mode1_form2); ( void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2 );
/*! /*!
Reads i_blocks of mode1 sectors from cd device into data starting Reads i_blocks of mode1 sectors from cd device into data starting
from lsn. from lsn.
Returns 0 if no error. Returns 0 if no error.
*/ */
int (*read_mode1_sectors) (void *p_env, void *p_buf, lsn_t i_lsn, int (*read_mode1_sectors)
bool mode1_form2, unsigned int i_blocks); ( void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2,
unsigned int i_blocks );
bool (*read_toc) ( void *p_env ) ; bool (*read_toc) ( void *p_env ) ;