/*! Convert a MSF into the corresponding LBA. CDIO_INVALID_LBA is returned if there is an error. */ lba_t cdio_msf_to_lba (const msf_t *msf) { uint32_t lba = 0; cdio_assert (msf != 0); lba = cdio_from_bcd8 (msf->m); lba *= CDIO_CD_SECS_PER_MIN; lba += cdio_from_bcd8 (msf->s); lba *= CDIO_CD_FRAMES_PER_SEC; lba += cdio_from_bcd8 (msf->f); return lba; }
/*! Playing starting at given MSF through analog output @param p_cdio the CD object to be acted upon. */ driver_return_code_t audio_play_msf_win32ioctl (void *p_user_data, msf_t *p_start_msf, msf_t *p_end_msf) { const _img_private_t *p_env = p_user_data; CDROM_PLAY_AUDIO_MSF play; DWORD dw_bytes_returned; play.StartingM = cdio_from_bcd8(p_start_msf->m); play.StartingS = cdio_from_bcd8(p_start_msf->s); play.StartingF = cdio_from_bcd8(p_start_msf->f); play.EndingM = cdio_from_bcd8(p_end_msf->m); play.EndingS = cdio_from_bcd8(p_end_msf->s); play.EndingF = cdio_from_bcd8(p_end_msf->f); bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_PLAY_AUDIO_MSF, &play, sizeof(play), NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { windows_error(CDIO_LOG_INFO, GetLastError()); return DRIVER_OP_ERROR; } return DRIVER_OP_SUCCESS; }
/*! Playing starting at given MSF through analog output @param p_cdio the CD object to be acted upon. */ driver_return_code_t audio_play_msf_win32ioctl (void *p_user_data, msf_t *p_start_msf, msf_t *p_end_msf) { const _img_private_t *p_env = p_user_data; CDROM_PLAY_AUDIO_MSF play; DWORD dw_bytes_returned; play.StartingM = cdio_from_bcd8(p_start_msf->m); play.StartingS = cdio_from_bcd8(p_start_msf->s); play.StartingF = cdio_from_bcd8(p_start_msf->f); play.EndingM = cdio_from_bcd8(p_end_msf->m); play.EndingS = cdio_from_bcd8(p_end_msf->s); play.EndingF = cdio_from_bcd8(p_end_msf->f); bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_PLAY_AUDIO_MSF, &play, sizeof(play), NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { char *psz_msg = NULL; long int i_err = GetLastError(); FORMAT_ERROR(i_err, psz_msg); if (psz_msg) cdio_info("Error: %s", psz_msg); else cdio_info("Error: %ld", i_err); LocalFree(psz_msg); return DRIVER_OP_ERROR; } return DRIVER_OP_SUCCESS; }
/*! Playing CD through analog output at the given MSF. @param p_cdio the CD object to be acted upon. */ static driver_return_code_t audio_play_msf_os2 (void *p_user_data, msf_t *p_start_msf, msf_t *p_end_msf) { _img_private_t *p_env = p_user_data; struct { UCHAR auch_sign[4]; BYTE uc_access_mode; BYTE uc_start_msf_f; BYTE uc_start_msf_s; BYTE uc_start_msf_m; BYTE uc_start_msf_reserved; BYTE uc_end_msf_f; BYTE uc_end_msf_s; BYTE uc_end_msf_m; BYTE uc_end_msf_reserved; } s_param = { .auch_sign = {'C', 'D', '0', '1'}, .uc_access_mode = 01, /* use MSF format */ }; ULONG ul_param_len; ULONG ul_data_len; ULONG rc; s_param.uc_start_msf_m = cdio_from_bcd8(p_start_msf->m); s_param.uc_start_msf_s = cdio_from_bcd8(p_start_msf->s); s_param.uc_start_msf_f = cdio_from_bcd8(p_start_msf->f); s_param.uc_end_msf_m = cdio_from_bcd8(p_end_msf->m); s_param.uc_end_msf_s = cdio_from_bcd8(p_end_msf->s); s_param.uc_end_msf_f = cdio_from_bcd8(p_end_msf->f); rc = DosDevIOCtl( p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_PLAYAUDIO, &s_param, sizeof( s_param ), &ul_param_len, NULL, 0, &ul_data_len ); if( rc ) { cdio_warn("audio_play_msf_os2 : DosDevIOCtl(PLAYAUDIO) = 0x%lx\n", rc ); return DRIVER_OP_ERROR; } return DRIVER_OP_SUCCESS; }
/*! Playing starting at given MSF through analog output @param p_cdio the CD object to be acted upon. */ static driver_return_code_t audio_play_msf_freebsd (void *p_user_data, msf_t *p_start_msf, msf_t *p_end_msf) { const _img_private_t *p_env = p_user_data; struct ioc_play_msf freebsd_play_msf; freebsd_play_msf.start_m = cdio_from_bcd8(p_start_msf->m); freebsd_play_msf.start_s = cdio_from_bcd8(p_start_msf->s); freebsd_play_msf.start_f = cdio_from_bcd8(p_start_msf->f); freebsd_play_msf.end_m = cdio_from_bcd8(p_end_msf->m); freebsd_play_msf.end_s = cdio_from_bcd8(p_end_msf->s); freebsd_play_msf.end_f = cdio_from_bcd8(p_end_msf->f); return ioctl(p_env->gen.fd, CDIOCPLAYMSF, &freebsd_play_msf); }
/* Return the number of seconds (discarding frame portion) of an MSF */ static inline unsigned int msf_seconds(msf_t *msf) { return cdio_from_bcd8(msf->m)*CDIO_CD_SECS_PER_MIN + cdio_from_bcd8(msf->s); }
/*! Read Audio Subchannel information @param p_cdio the CD object to be acted upon. */ static driver_return_code_t audio_read_subchannel_os2 (void *p_user_data, cdio_subchannel_t *p_subchannel) { _img_private_t *p_env = p_user_data; struct { UCHAR auch_sign[4]; } s_param = {{'C', 'D', '0', '1'}}; struct { BYTE uc_control_and_adr; BYTE uc_track_number; /* in BCD */ BYTE uc_index; /* in BCD */ BYTE uc_running_time_in_track_m; BYTE uc_running_time_in_track_s; BYTE uc_running_time_in_track_f; BYTE uc_reserved; BYTE uc_running_time_on_disk_m; BYTE uc_running_time_on_disk_s; BYTE uc_running_time_on_disk_f; } s_data_subchannel_q; struct { USHORT us_audio_status_bits; ULONG ul_start_msf; ULONG ul_end_msf; } s_data_audio_status; ULONG ul_data_device_status; ULONG ul_param_len; ULONG ul_data_len; ULONG rc; rc = DosDevIOCtl( p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETSUBCHANNELQ, &s_param, sizeof( s_param ), &ul_param_len, &s_data_subchannel_q, sizeof( s_data_subchannel_q ), &ul_data_len ); if( rc ) { cdio_warn("audio_read_subchannel_os2 : DosDevIOCtl(GETSUBCHANNELQ) = 0x%lx\n", rc ); return DRIVER_OP_ERROR; } rc = DosDevIOCtl( p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOSTATUS, &s_param, sizeof( s_param ), &ul_param_len, &s_data_audio_status, sizeof( s_data_audio_status ), &ul_data_len ); if( rc ) { cdio_warn("audio_read_subchannel_os2 : DosDevIOCtl(GETAUDIOSTATUS) = 0x%lx\n", rc ); return DRIVER_OP_ERROR; } rc = DosDevIOCtl( p_env->h_cd, IOCTL_CDROMDISK, CDROMDISK_DEVICESTATUS, &s_param, sizeof( s_param ), &ul_param_len, &ul_data_device_status, sizeof( ul_data_device_status ), &ul_data_len ); if( rc ) { cdio_warn("audio_read_subchannel_os2 : DosDevIOCtl(DEVICESTATUS) = 0x%lx\n", rc ); return DRIVER_OP_ERROR; } p_subchannel->track = cdio_from_bcd8(s_data_subchannel_q.uc_track_number); p_subchannel->index = cdio_from_bcd8(s_data_subchannel_q.uc_index); p_subchannel->abs_addr.m = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_on_disk_m); p_subchannel->abs_addr.s = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_on_disk_s); p_subchannel->abs_addr.f = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_on_disk_f); p_subchannel->rel_addr.m = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_in_track_m); p_subchannel->rel_addr.s = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_in_track_s); p_subchannel->rel_addr.f = cdio_to_bcd8(s_data_subchannel_q.uc_running_time_in_track_f); p_subchannel->address = s_data_subchannel_q.uc_control_and_adr & 0x0F; p_subchannel->control = ( s_data_subchannel_q.uc_control_and_adr >> 4 ) & 0x0F; if( ul_data_device_status & 0x1000 ) p_subchannel->audio_status = CDIO_MMC_READ_SUB_ST_PLAY; else if( s_data_audio_status.us_audio_status_bits & 1 ) p_subchannel->audio_status = CDIO_MMC_READ_SUB_ST_PAUSED; else if( s_data_audio_status.ul_start_msf == 0 && s_data_audio_status.ul_end_msf == 0 ) p_subchannel->audio_status = CDIO_MMC_READ_SUB_ST_NO_STATUS; else p_subchannel->audio_status = CDIO_MMC_READ_SUB_ST_COMPLETED; return DRIVER_OP_SUCCESS; }