首页 > 编程 > Java > 正文

一种计算CD标识的算法

2019-09-06 23:33:45
字体:
来源:转载
供稿:网友

                   
北 京 市167 信 箱(100036)  王 亚 军

---- 本 文 介 绍 了 关 于 音 乐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) {
/tret = ret + (n % 10);
/tn = 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 除, 消 掉 余 数 即 可。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选