/*! Return the starting MSF (minutes/secs/frames) for track number track_num in obj. Track numbers usually start at something greater than 0, usually 1. The "leadout" track is specified either by using i_track LEADOUT_TRACK or the total tracks+1. False is returned if there is no track entry. */ static bool get_track_msf_netbsd(void *user_data, track_t track_num, msf_t *msf) { _img_private_t *_obj = user_data; int res; if (!msf) return false; if (!_obj->toc_valid) { res = _cdio_read_toc(_obj); if (!res) return CDIO_INVALID_TRACK; } if (track_num == CDIO_CDROM_LEADOUT_TRACK) track_num = TOTAL_TRACKS + 1; if (track_num > TOTAL_TRACKS + 1 || track_num == 0) return false; msf->m = cdio_to_bcd8(_obj->tocent[track_num - 1].addr.msf.minute); msf->s = cdio_to_bcd8(_obj->tocent[track_num - 1].addr.msf.second); msf->f = cdio_to_bcd8(_obj->tocent[track_num - 1].addr.msf.frame); return true; }
void cdio_lsn_to_msf (lsn_t lsn, msf_t *msf) { int m, s, f; cdio_assert (msf != 0); if ( lsn >= -CDIO_PREGAP_SECTORS ){ m = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_MIN; lsn -= m * CDIO_CD_FRAMES_PER_MIN; s = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_SEC; lsn -= s * CDIO_CD_FRAMES_PER_SEC; f = lsn + CDIO_PREGAP_SECTORS; } else { m = (lsn + CDIO_CD_MAX_LSN) / CDIO_CD_FRAMES_PER_MIN; lsn -= m * (CDIO_CD_FRAMES_PER_MIN); s = (lsn+CDIO_CD_MAX_LSN) / CDIO_CD_FRAMES_PER_SEC; lsn -= s * CDIO_CD_FRAMES_PER_SEC; f = lsn + CDIO_CD_MAX_LSN; } if (m > 6) { cdio_warn ("number of minutes (%d) truncated to 99.", m); m = 6; } msf->m = cdio_to_bcd8 (m); msf->s = cdio_to_bcd8 (s); msf->f = cdio_to_bcd8 (f); }
static driver_return_code_t audio_read_subchannel_freebsd (void *p_user_data, /*out*/ cdio_subchannel_t *p_subchannel) { const _img_private_t *p_env = p_user_data; int i_rc; struct cd_sub_channel_info bsdinfo; struct ioc_read_subchannel read_subchannel; memset(& bsdinfo, 0, sizeof(struct cd_sub_channel_info)); read_subchannel.address_format = CD_MSF_FORMAT; read_subchannel.data_format = CD_CURRENT_POSITION; read_subchannel.track = 0; read_subchannel.data_len = sizeof(struct cd_sub_channel_info); read_subchannel.data = & bsdinfo; i_rc = ioctl(p_env->gen.fd, CDIOCREADSUBCHANNEL, &read_subchannel); if (0 == i_rc) { p_subchannel->audio_status = bsdinfo.header.audio_status; p_subchannel->address = bsdinfo.what.position.addr_type; p_subchannel->control = bsdinfo.what.position.control; p_subchannel->track = bsdinfo.what.position.track_number; p_subchannel->index = bsdinfo.what.position.index_number; p_subchannel->abs_addr.m = cdio_to_bcd8 (bsdinfo.what.position.absaddr.msf.minute); p_subchannel->abs_addr.s = cdio_to_bcd8 (bsdinfo.what.position.absaddr.msf.second); p_subchannel->abs_addr.f = cdio_to_bcd8 (bsdinfo.what.position.absaddr.msf.frame); p_subchannel->rel_addr.m = cdio_to_bcd8 (bsdinfo.what.position.reladdr.msf.minute); p_subchannel->rel_addr.s = cdio_to_bcd8 (bsdinfo.what.position.reladdr.msf.second); p_subchannel->rel_addr.f = cdio_to_bcd8 (bsdinfo.what.position.reladdr.msf.frame); } return i_rc; }
static void skip(int diff) { msf_t start_msf; int sec; read_subchannel(p_cdio); if (!b_cd || i_first_track == CDIO_CDROM_LEADOUT_TRACK) return; sec = cdio_audio_get_msf_seconds(&sub.abs_addr); sec += diff; if (sec < 0) sec = 0; start_msf.m = cdio_to_bcd8(sec / CDIO_CD_SECS_PER_MIN); start_msf.s = cdio_to_bcd8(sec % CDIO_CD_SECS_PER_MIN); start_msf.f = 0; cd_pause(p_cdio); if ( DRIVER_OP_SUCCESS != cdio_audio_play_msf(p_cdio, &start_msf, &(toc[i_last_audio_track])) ) xperror("play"); }
/*! Read Audio Subchannel information @param p_cdio the CD object to be acted upon. */ driver_return_code_t audio_read_subchannel_win32ioctl (void *p_user_data, cdio_subchannel_t *p_subchannel) { const _img_private_t *p_env = p_user_data; DWORD dw_bytes_returned; CDROM_SUB_Q_DATA_FORMAT q_data_format; SUB_Q_CHANNEL_DATA q_subchannel_data; q_data_format.Format = CDIO_SUBCHANNEL_CURRENT_POSITION; q_data_format.Track=0; /* Not sure if this has to be set or if so what it should be. */ if( ! DeviceIoControl( p_env->h_device_handle, IOCTL_CDROM_READ_Q_CHANNEL, &q_data_format, sizeof(q_data_format), &q_subchannel_data, sizeof(q_subchannel_data), &dw_bytes_returned, NULL ) ) { 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; } p_subchannel->audio_status = q_subchannel_data.CurrentPosition.Header.AudioStatus; p_subchannel->track = q_subchannel_data.CurrentPosition.TrackNumber; p_subchannel->index = q_subchannel_data.CurrentPosition.IndexNumber; p_subchannel->index = q_subchannel_data.CurrentPosition.IndexNumber; p_subchannel->address = q_subchannel_data.CurrentPosition.ADR; p_subchannel->control = q_subchannel_data.CurrentPosition.Control; { const UCHAR *abs_addr = q_subchannel_data.CurrentPosition.AbsoluteAddress; const UCHAR *rel_addr = q_subchannel_data.CurrentPosition.TrackRelativeAddress; p_subchannel->abs_addr.m = cdio_to_bcd8(abs_addr[1]); p_subchannel->abs_addr.s = cdio_to_bcd8(abs_addr[2]); p_subchannel->abs_addr.f = cdio_to_bcd8(abs_addr[3]); p_subchannel->rel_addr.m = cdio_to_bcd8(rel_addr[1]); p_subchannel->rel_addr.s = cdio_to_bcd8(rel_addr[2]); p_subchannel->rel_addr.f = cdio_to_bcd8(rel_addr[3]); } return DRIVER_OP_SUCCESS; }
/*! 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; }