📄 bcjq057.txt
字号:
C++ Builder开发者:程序员之家
var how_many_ads = 3;
var now = new Date()
var sec = now.getSeconds()
var ad = sec % how_many_ads;
ad +=1;
首页
| 控件天堂 | 控件使用
| 编程技巧
| 源代码 | 编程工具 |
系统补丁 | 电子书籍 | 技术论坛
| 相关链接
if (ad==1) {document.write(''+'');}
if (ad==2) {document.write(''+'');}
if (ad==3) {document.write(''+'');}
var marqueecontents=''+scroll_text+''
if (document.all)
document.write(''+marqueecontents+'')
function regenerate(){
window.location.reload()
}
function regenerate2(){
if (document.layers){
setTimeout("window.onresize=regenerate",450)
intializemarquee()
}
}
function intializemarquee(){
document.cmarquee01.document.cmarquee02.document.write(marqueecontents)
document.cmarquee01.document.cmarquee02.document.close()
thelength=document.cmarquee01.document.cmarquee02.document.height
scrollit()
}
function scrollit(){
if (document.cmarquee01.document.cmarquee02.top>=thelength*(-1)){
document.cmarquee01.document.cmarquee02.top-=speed
setTimeout("scrollit()",100)
}
else{
document.cmarquee01.document.cmarquee02.top=marqueeheight
scrollit()
}
}
window.onload=regenerate2
当前位置
:
编程技巧
一
种 计 算CD 标 识 的 算 法
本 文 介 绍 了 关 于 音 乐CD 的 红 皮 书 格 式。 文 章
从 如 何 根 据 数 据 格 式, 调 用Windows MCI 接 口 函
数, 利 用 一 定 算 法 计 算CD 之ID 号, 用 来 唯 一 标
识CD 等 方 面 阐 述 和 说 明, 具 有 一 定 的 应 用 价
值。
一、 红 皮 书 格 式
----在 光 盘 格 式 家 族 中, 大
家 较 熟 悉 的 有 红 皮 书、 黄 皮 书、 白 皮 书 以 及
桔 皮 书 等 多 种 标 准。 这 些 格 式 有 个 共 同 的 特
点, 就 是 光 盘 最 小 分 配 单 位 是 长 度 为2352 个 字
节 的 扇 区; 当 然, 并 不 是 所 有 的2352 个 字 节 都
可 为 用 户 所 用, 这 要 看 具 体 是 哪 个 标 准。 例
如, 黄 皮 书 格 式 中2352 个 字 节 要 扣 除 一 些 检 错
和 纠 错 的 开 销, 只 有2048 个 字 节 是 真 正 存 放 用
户 数 据 的。
----红 皮 书 格 式 是1980 年PHILIP
和SONY 联 合 颁 布 的, 又 称CD -DA 格 式, 是 为 控 制
音 频CD 建 立 的 标 准。 它 是 国 际 标 准ISO10149。 红
皮 书 标 准 规 范 了 光 盘 尺 寸、 塑 料 的 光 参 数、
录 放 环 境、 信 号 测 量、 保 真 度 以 及 音 乐 波 形
数 字 文 件 结 构。 红 皮 书 音 频 的 数 字 化 方 式 用44.1kHz
的 采 样 频 率、16 级 量 化 电 平 而 且 是 双 通 道 记
录 和 线 形 格 式。 现 已 成 为 音 乐 工 业 中 的 事 实
标 准。 主 要 有 以 下 内 容:
最 多99 首 歌 曲(track, 即 音 轨);
每 扇 区2352 字 节 均 用 来 存 放 声 音 数 据;
声 音 数 据 为 采 样 率44.1K、16 比 特 量 化 的PCM 信
号;
立 体 声;
无 目 录 和 文 件 结 构, 连 续 存 放PCM 信 号;
播 放 时 按 每 秒75 扇 区 的 速 度;
每 张 光 盘 最 多74 分 钟。
----音 频 数 据 不 像 其 他
计 算 机 数 据( 如 程 序 文 件) 那 样 对 错 误 具
有 极 大 的 敏 感 性( 一 般 对 误 码 具 敏 感 性 的
数 据 不 能 容 忍1 比 特 的 错 误), 因 此 每 扇 区
的2352 个 字 节 无 需 额 外 的 检 错 纠 错 的 开 销,
均 可 用 来 存 放 音 频 数 据。 这 样, 每 个 扇 区
能 存 放 的 音 乐 时 间 为2352/(16/8 ×2 ×44100)=1/75
秒, 因 此 播 放 速 度 为75 扇 区 / 秒。 扇 区 地 址
与 播 放 时 间 具 有 一 一 对 应 的 关 系; 在CD -DA
格 式 中, 用 时 间MSF 格 式 表 示, 标 记 为 00:00:00
格 式:
----M: 分 钟 数, 以 一 个 字
节 表 示;
----S: 秒 数, 范 围0 ~59, 以
一 个 字 节 表 示;
----F: 扇 区 数, 范 围0 ~74,
以 一 个 字 节 表 示, 代 表 有 多 少 个1/75 秒。
----在ISO 9660 标 准 下, 单 张
的 CD -ROM 被 定 义 为 一 个" 卷", 前150 个
扇 区 用 于 保 存 各 个 音 轨 的 起 始 时 间 以 及
光 盘 本 身 的 卷 标、 版 权 等 信 息。 所 以, 从MSF
到 绝 对 扇 区 地 址 的 转 换 关 系 为:
---- Address = M * 60 * 75 + S
* 75 + F + 150 ;
----本 人 在 开 发 一 个 个
人CD 收 藏 数 据 库 时 发 现, 各 个CD 出 版 公 司 都
有 自 己 的CD 编 号 规 范, 无 法 统 一, 如: DG 437
667 -2。 因 此, 有 必 要 采 用 一 种 算 法 唯 一 标
识 单 张CD。 基 于 以 上 分 析, 采 用 如 下 算 法,
事 实 证 明 是 可 行 的。
二、 算 法 说 明( 程 序 框 架)
struct toc {
int min;
int sec;
int frame;
};// 单 个 音 轨 内 容 表
struct toc cdtoc[100];
// 结 构 数 组, 用 来 存 放 各 个 音 轨 的 内 容
int read_cdtoc_from_drive(void)
{
/ * 将CD 的 内 容 表 读 入cdtoc[] 结 构 数 组 */
return (tot_trks);
}
int cddb_sum(int n)
{
int ret;
/ * 将 传 入 参 数 的 每 位 数 据 累 加 */
ret = 0;
while (n > 0) {
ret = ret + (n % 10);
n = n / 10;
}
return (ret);
}
unsigned long cddb_discid(int tot_trks)
{
int i, t = 0, n = 0;
i = 0;
while (i
三、 使 用
----假 设 你 的 编 译 器 支
持32 位 整 数, cddb_discid 函 数 计 算discid, 基 于CD
的 内 容 表, 按 照MSF 格 式, 故 意 忽 略 了 扇 区
数, 函 数 接 收tot_trks 参 数(CD 的 音 轨 总 数),
返 回discid 这 个 整 数。 假 设cdtoc[] 是 一 个 结 构
数 组, 每 个 结 构 包 含 分 钟 数、 秒 数 和 扇 区
数 三 个 域, 它 们 实 际 上 是 每 个 音 轨 的 分 钟
数、 秒 数 和 扇 区 数 的 偏 移 量。 这 些 信 息 从CD
的 内 容 表 中 读 出, 数 组 中 实 际 上 有tot_trks +
1 个 元 素, 最 后 一 个 是 个 虚 拟 音 轨, 即 最
外 一 个 音 轨 末 端 的 偏 移 量, 或 称 为 顶 头 音
轨( 也 称 音 轨0xAA), 函 数 循 环 检 测 内 容 表
中 的 每 个 音 轨, 计 算 每 个 音 轨 的(M * 60) + S(
按 秒 计 算 偏 移 量), 并 把 结 果 给cddb_sum() 函
数, 该 函 数 把 数 据 中 的 每 个 数 字 累 加, 每
个 音 轨 的 结 果 保 存 在 变 量n 中。
----循 环 结 束 时
用 顶 头 音 轨 的 偏 移 量(M *60 +S) 减 去
第 一 个 音 轨 的 偏 移 量 (M *60 +S), 按 秒
计 算disk 的 长 度。
用n 对0xff 取 余, 将 结 果 左 移24 位。
把t 左 移8 位。
----把2、3 所 得 结 果 连 同tot_trks
进 行 或 运 算, 结 果 便 是diskid。
----为 了 建 库 方 便,diskid
用16 进 制 代 表, 如 果 少 于8 位 字 符 串, 前 面
补0,( 如3a8f07 变 为003a8f07), 为 方 便 起 见, 其
中 的 字 母 用 小 写。
----使 用MS -Windows MCI 接 口
的 用 户 应 注 意:
----Windows MCI 接 口 不 提 供
顶 头 音 轨 的MSF 位 置, 因 此, 你 必 须 通 过 计
算 最 后 一 个 音 轨 的 起 始 位 置 加 上 最 后 一
个 音 轨 的 长 度 来 得 到 它。 然 而,MCI 接 口 返
回 最 后 一 个 音 轨 的 长 度 比CD 的Toc 中 所 存 的
长 度 少 一 桢, 大 多 数 情 况 下, 这 不 影 响 产
生 的ID, 因 为, 计 算disk ID 时, 总 要 截 掉 桢
数。 然 而, 如 果 顶 头 音 轨 的 桢 数 为0, 秒 数
会 减 一, 桢 数 成 为74, 例 如: 一 张CD 最 后 一
个 音 轨 在 偏 移 量48m 32s 12f 处, 该 音 轨 长 度 为2m
50s 63f, 顶 头 偏 移 量51m 23s 0f, Windows MCI 错 误 报
告 长 度 为2m 50s 62f, 这 会 产 生51m 22s 74f 的 顶 头
偏 移 量, 这 样 导 致 长 度 被 截 断 一 秒, 从 而
使 得disk ID 不 正 确。 这 样, 当 你 计 算 顶 头 位
置 的 时 候, 在 最 后 一 个 音 轨 的 长 度 上 加 上
一 桢。
----对 于Windows 客 户 来 说,
按 照MSF 格 式 计 算 顶 头 的 最 简 便 的 方 法 是:
(offset_minutes * 60 * 75) +(offset_seconds * 75) +offset_frames
+ (length_minutes * 60 * 75) +(length_seconds * 75) +
length_frames +1=X
X 是 按 桢 计 算 的 顶 头 偏 移 量, 若 按 秒 计
算, 只 需 简 单 地 用75 除, 消 掉 余 数 即 可。
北 京 市167 信 箱(100036) 王 亚 军
if (ad==1) {document.write(''+'');}
if (ad==2) {document.write(''+'');}
if (ad==3) {document.write(''+'');}
C++ Builder开发者®
2000年06月01日 站长:唐朝