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 -*-
$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>
@@ -49,10 +49,7 @@ extern "C" {
/*! 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;
uint8_t level[4];
} 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>
@@ -180,14 +180,34 @@ typedef enum {
/*! Page codes for MODE SENSE and MODE SET. */
#define CDIO_MMC_R_W_ERROR_PAGE 0x01
#define CDIO_MMC_WRITE_PARMS_PAGE 0x05
#define CDIO_MMC_AUDIO_CTL_PAGE 0x0e
#define CDIO_MMC_CDR_PARMS_PAGE 0x0d
#define CDIO_MMC_AUDIO_CTL_PAGE 0x0e
#define CDIO_MMC_POWER_PAGE 0x1a
#define CDIO_MMC_FAULT_FAIL_PAGE 0x1c
#define CDIO_MMC_TO_PROTECT_PAGE 0x1d
#define CDIO_MMC_CAPABILITIES_PAGE 0x2a
#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. */
#define CDIO_MMC_GET_CONF_ALL_FEATURES 0 /**< all features without regard
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 );
/** 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, ...)
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) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#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>
@@ -194,6 +194,20 @@ check_mounts_linux(const char *mtab)
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
@@ -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.
@@ -1268,7 +1282,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
char *psz_source;
cdio_funcs_t _funcs = {
// .audio_get_volume = audio_get_volume_linux,
.audio_get_volume = audio_get_volume_linux,
.audio_pause = audio_pause_linux,
.audio_play_msf = audio_play_msf_linux,
.audio_play_track_index= audio_play_track_index_linux,

View File

@@ -1,6 +1,6 @@
/* 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>
@@ -154,6 +154,30 @@ set_speed_mmc (void *p_user_data, int 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
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) 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_hwinfo_t hwinfo;
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",
"Vendor" , hwinfo.psz_vendor,
"Model" , hwinfo.psz_model,
@@ -1162,32 +1162,54 @@ main(int argc, const char *argv[])
report( stdout, "audio status: "); fflush(stdout);
if (DRIVER_OP_SUCCESS == rc) {
bool b_volume = false;
bool b_position = false;
switch (subchannel.audio_status) {
case CDIO_MMC_READ_SUB_ST_INVALID:
report( stdout, "invalid\n" ); break;
case CDIO_MMC_READ_SUB_ST_PLAY:
b_playing_audio = true;
b_position = true;
b_volume = true;
report( stdout, "playing" ); break;
case CDIO_MMC_READ_SUB_ST_PAUSED:
b_position = true;
b_volume = true;
report( stdout, "paused" ); break;
case CDIO_MMC_READ_SUB_ST_COMPLETED:
report( stdout, "completed\n"); break;
case CDIO_MMC_READ_SUB_ST_ERROR:
report( stdout, "error\n" ); break;
case CDIO_MMC_READ_SUB_ST_NO_STATUS:
b_volume = true;
report( stdout, "no status\n" ); break;
default:
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",
subchannel.abs_addr.msf.m,
subchannel.abs_addr.msf.s,
subchannel.rel_addr.msf.m,
subchannel.rel_addr.msf.s,
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) {
report( stdout, "not implemented\n" );