audio.h: redo audio volume levels a little.

mmc.{c,h}: attempt to get audio ports/selections via MMC.
cd-info.c: show volume output levels in a cleaner fashion.
This commit is contained in:
rocky
2005-03-02 04:23:59 +00:00
parent 7441d6a1ec
commit 3abb1badf9
5 changed files with 100 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/* -*- c -*- /* -*- c -*-
$Id: audio.h,v 1.2 2005/03/01 10:53:15 rocky Exp $ $Id: audio.h,v 1.3 2005/03/02 04:23:59 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -49,10 +49,7 @@ extern "C" {
/*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */ /*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
typedef struct cdio_audio_volume_s typedef struct cdio_audio_volume_s
{ {
uint8_t channel0; uint8_t level[4];
uint8_t channel1;
uint8_t channel2;
uint8_t channel3;
} cdio_audio_volume_t; } cdio_audio_volume_t;

View File

@@ -1,5 +1,5 @@
/* /*
$Id: mmc.h,v 1.15 2005/03/01 10:53:15 rocky Exp $ $Id: mmc.h,v 1.16 2005/03/02 04:24:00 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -180,14 +180,34 @@ typedef enum {
/*! Page codes for MODE SENSE and MODE SET. */ /*! Page codes for MODE SENSE and MODE SET. */
#define CDIO_MMC_R_W_ERROR_PAGE 0x01 #define CDIO_MMC_R_W_ERROR_PAGE 0x01
#define CDIO_MMC_WRITE_PARMS_PAGE 0x05 #define CDIO_MMC_WRITE_PARMS_PAGE 0x05
#define CDIO_MMC_AUDIO_CTL_PAGE 0x0e
#define CDIO_MMC_CDR_PARMS_PAGE 0x0d #define CDIO_MMC_CDR_PARMS_PAGE 0x0d
#define CDIO_MMC_AUDIO_CTL_PAGE 0x0e
#define CDIO_MMC_POWER_PAGE 0x1a #define CDIO_MMC_POWER_PAGE 0x1a
#define CDIO_MMC_FAULT_FAIL_PAGE 0x1c #define CDIO_MMC_FAULT_FAIL_PAGE 0x1c
#define CDIO_MMC_TO_PROTECT_PAGE 0x1d #define CDIO_MMC_TO_PROTECT_PAGE 0x1d
#define CDIO_MMC_CAPABILITIES_PAGE 0x2a #define CDIO_MMC_CAPABILITIES_PAGE 0x2a
#define CDIO_MMC_ALL_PAGES 0x3f #define CDIO_MMC_ALL_PAGES 0x3f
PRAGMA_BEGIN_PACKED
struct mmc_audio_volume_entry_s
{
uint8_t selection; /* Only the lower 4 bits are used. */
uint8_t volume;
} GNUC_PACKED;
typedef struct mmc_audio_volume_entry_s mmc_audio_volume_entry_t;
/*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
struct mmc_audio_volume_s
{
mmc_audio_volume_entry_t port[4];
} GNUC_PACKED;
typedef struct mmc_audio_volume_s mmc_audio_volume_t;
PRAGMA_END_PACKED
/*! Return type codes for GET_CONFIGURATION. */ /*! Return type codes for GET_CONFIGURATION. */
#define CDIO_MMC_GET_CONF_ALL_FEATURES 0 /**< all features without regard #define CDIO_MMC_GET_CONF_ALL_FEATURES 0 /**< all features without regard
to currency. */ to currency. */
@@ -501,6 +521,13 @@ int mmc_get_media_changed(const CdIo_t *p_cdio);
*/ */
char * mmc_get_mcn ( const CdIo_t *p_cdio ); char * mmc_get_mcn ( const CdIo_t *p_cdio );
/** Get the output port volumes and port selections used on AUDIO PLAY
commands via a MMC MODE SENSE command using the CD Audio Control
Page.
*/
driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/
mmc_audio_volume_t *p_volume);
/*! /*!
Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...) Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...)
Is it possible for an interface to have serveral? If not this Is it possible for an interface to have serveral? If not this

View File

@@ -1,5 +1,5 @@
/* /*
$Id: _cdio_linux.c,v 1.34 2005/03/01 11:00:49 rocky Exp $ $Id: _cdio_linux.c,v 1.35 2005/03/02 04:24:00 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.34 2005/03/01 11:00:49 rocky Exp $"; static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.35 2005/03/02 04:24:00 rocky Exp $";
#include <string.h> #include <string.h>
@@ -194,6 +194,20 @@ check_mounts_linux(const char *mtab)
return NULL; return NULL;
} }
/*!
Get the volume of an audio CD.
@param p_cdio the CD object to be acted upon.
*/
static driver_return_code_t
audio_get_volume_linux (void *p_user_data,
/*out*/ cdio_audio_volume_t *p_volume)
{
const _img_private_t *p_env = p_user_data;
return ioctl(p_env->gen.fd, CDROMVOLREAD, p_volume);
}
/*! /*!
Pause playing CD through analog output Pause playing CD through analog output
@@ -265,7 +279,7 @@ audio_resume_linux (void *p_user_data)
} }
/*! /*!
Resume playing an audio CD. Set the volume of an audio CD.
@param p_cdio the CD object to be acted upon. @param p_cdio the CD object to be acted upon.
@@ -1268,7 +1282,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
char *psz_source; char *psz_source;
cdio_funcs_t _funcs = { cdio_funcs_t _funcs = {
// .audio_get_volume = audio_get_volume_linux, .audio_get_volume = audio_get_volume_linux,
.audio_pause = audio_pause_linux, .audio_pause = audio_pause_linux,
.audio_play_msf = audio_play_msf_linux, .audio_play_msf = audio_play_msf_linux,
.audio_play_track_index= audio_play_track_index_linux, .audio_play_track_index= audio_play_track_index_linux,

View File

@@ -1,6 +1,6 @@
/* Common Multimedia Command (MMC) routines. /* Common Multimedia Command (MMC) routines.
$Id: mmc.c,v 1.18 2005/03/01 10:53:15 rocky Exp $ $Id: mmc.c,v 1.19 2005/03/02 04:24:00 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -154,6 +154,30 @@ set_speed_mmc (void *p_user_data, int i_speed)
return mmc_set_speed( p_env->cdio, i_speed ); return mmc_set_speed( p_env->cdio, i_speed );
} }
/** Get the output port volumes and port selections used on AUDIO PLAY
commands via a MMC MODE SENSE command using the CD Audio Control
Page.
*/
driver_return_code_t
mmc_audio_get_volume( CdIo_t *p_cdio, /*out*/ mmc_audio_volume_t *p_volume )
{
uint8_t buf[16];
int i_rc = mmc_mode_sense(p_cdio, buf, sizeof(buf), CDIO_MMC_AUDIO_CTL_PAGE);
if ( DRIVER_OP_SUCCESS == i_rc ) {
p_volume->port[0].selection = 0xF & buf[8];
p_volume->port[0].volume = buf[9];
p_volume->port[1].selection = 0xF & buf[10];
p_volume->port[1].volume = buf[11];
p_volume->port[2].selection = 0xF & buf[12];
p_volume->port[2].volume = buf[13];
p_volume->port[3].selection = 0xF & buf[14];
p_volume->port[3].volume = buf[15];
return DRIVER_OP_SUCCESS;
}
return i_rc;
}
/*! /*!
On input a MODE_SENSE command was issued and we have the results On input a MODE_SENSE command was issued and we have the results
in p. We interpret this and return a bit mask set according to the in p. We interpret this and return a bit mask set according to the

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cd-info.c,v 1.125 2005/03/01 11:29:52 rocky Exp $ $Id: cd-info.c,v 1.126 2005/03/02 04:24:00 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org> Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org>
@@ -949,7 +949,7 @@ main(int argc, const char *argv[])
CdIo_t *p_cdio = cdio_open(source_name, driver_id); CdIo_t *p_cdio = cdio_open(source_name, driver_id);
cdio_hwinfo_t hwinfo; cdio_hwinfo_t hwinfo;
printf("Drive %s\n", *d); printf("Drive %s\n", *d);
if (scsi_mmc_get_hwinfo(p_cdio, &hwinfo)) { if (mmc_get_hwinfo(p_cdio, &hwinfo)) {
printf("%-8s: %s\n%-8s: %s\n%-8s: %s\n", printf("%-8s: %s\n%-8s: %s\n%-8s: %s\n",
"Vendor" , hwinfo.psz_vendor, "Vendor" , hwinfo.psz_vendor,
"Model" , hwinfo.psz_model, "Model" , hwinfo.psz_model,
@@ -1162,32 +1162,54 @@ main(int argc, const char *argv[])
report( stdout, "audio status: "); fflush(stdout); report( stdout, "audio status: "); fflush(stdout);
if (DRIVER_OP_SUCCESS == rc) { if (DRIVER_OP_SUCCESS == rc) {
bool b_volume = false;
bool b_position = false;
switch (subchannel.audio_status) { switch (subchannel.audio_status) {
case CDIO_MMC_READ_SUB_ST_INVALID: case CDIO_MMC_READ_SUB_ST_INVALID:
report( stdout, "invalid\n" ); break; report( stdout, "invalid\n" ); break;
case CDIO_MMC_READ_SUB_ST_PLAY: case CDIO_MMC_READ_SUB_ST_PLAY:
b_playing_audio = true; b_playing_audio = true;
b_position = true;
b_volume = true;
report( stdout, "playing" ); break; report( stdout, "playing" ); break;
case CDIO_MMC_READ_SUB_ST_PAUSED: case CDIO_MMC_READ_SUB_ST_PAUSED:
b_position = true;
b_volume = true;
report( stdout, "paused" ); break; report( stdout, "paused" ); break;
case CDIO_MMC_READ_SUB_ST_COMPLETED: case CDIO_MMC_READ_SUB_ST_COMPLETED:
report( stdout, "completed\n"); break; report( stdout, "completed\n"); break;
case CDIO_MMC_READ_SUB_ST_ERROR: case CDIO_MMC_READ_SUB_ST_ERROR:
report( stdout, "error\n" ); break; report( stdout, "error\n" ); break;
case CDIO_MMC_READ_SUB_ST_NO_STATUS: case CDIO_MMC_READ_SUB_ST_NO_STATUS:
b_volume = true;
report( stdout, "no status\n" ); break; report( stdout, "no status\n" ); break;
default: default:
report( stdout, "Oops: unknown\n" ); report( stdout, "Oops: unknown\n" );
} }
if (subchannel.audio_status == CDIO_MMC_READ_SUB_ST_PLAY ||
subchannel.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED) { if (b_position)
report( stdout, " at: %02d:%02d abs / %02d:%02d track %d\n", report( stdout, " at: %02d:%02d abs / %02d:%02d track %d\n",
subchannel.abs_addr.msf.m, subchannel.abs_addr.msf.m,
subchannel.abs_addr.msf.s, subchannel.abs_addr.msf.s,
subchannel.rel_addr.msf.m, subchannel.rel_addr.msf.m,
subchannel.rel_addr.msf.s, subchannel.rel_addr.msf.s,
subchannel.track ); subchannel.track );
if (b_volume) {
cdio_audio_volume_t volume;
if (DRIVER_OP_SUCCESS == cdio_audio_get_volume (p_cdio, &volume)) {
uint8_t i=0;
for (i=0; i<4; i++) {
uint8_t i_level = volume.level[i];
report( stdout,
"volume level port %d: %3d (0..255) %3d (0..100)\n",
i, i_level, (i_level*100+128) / 256 );
}
} else
report( stdout, " can't get volume levels\n" );
} }
} else if (DRIVER_OP_UNSUPPORTED == rc) { } else if (DRIVER_OP_UNSUPPORTED == rc) {
report( stdout, "not implemented\n" ); report( stdout, "not implemented\n" );