Sau đó một bộ chuyển đổi tƣơng tự-số đo (mẫu hoá) dòng điện áp tại các quãng thời gian đều nhau. Ví dụ nhƣ, trong một đĩa compact có tới 44,100 mẫu đƣợc lấy mỗi giây. Mỗi điện áp mẫu hoá nhận đƣợc sẽ đƣợc chuyển đổi sang dạng số nguyên 16-bit. Một đĩa CD chứa 2 kênh dữ liệu: một cho tai trái, và một cho tai phải (đối với âm thanh dạng stereo). Hai kênh đƣợc thu thanh độc lập, đƣợc đặt theo cạnh (side) trên đĩa compact (dữ liệu cho các kênh trái và phải luân phiên nhau...trái, phải, trái, phải, ...). Dữ liệu nhận đƣợc từ quá trình thu thanh PCM là một hàm theo thời gian.
2.1.3 Mố số cấu trúc file âm thanh số.
2.1.3.1 Tệp Wave (*.wav)
Đây là dạng của Microsoft Windows. Các tệp Wave của Windows ứng dụng cho cả 2 dạng tệp âm thanh nổi (stereo) và dạng đơn (mono) với một tập các độ phân giải và tần số lấy mẫu. Kiểu tệp này cho phép sự định rõ RIFF (Resource Information File Format), và cho phép thông tin phụ của ngƣời sử dụng đƣợc nhúng vào và đƣợc ghi cùng với tệp âm thanh. Dạng âm thanh PCM dùng cho Windows chuẩn chứa dữ liệu đã đƣợc mã hoá, dữ liệu đã đƣợc định dạng theo kiểu điều biến mã xung dạng không bị nén.
Do dạng tệp Wave là một dạng âm thanh tự nhiên đƣợc Microsoft Windows sử dụng, nên nó trở thành một trong các dạng âm thanh phổ biến nhất. Nói chung, cấu trúc của nó đƣợc phát triển dựa trên dạng khởi đầu Interchange File Format (IFF) đƣợc Electronic Arts phát triển cho việc sử dụng trên Amiga. IFF cũng định hình khuôn dạng cơ sở của dạng âm thanh Aiff của Apple.
Tiếp theo IFF, Microsoft định nghĩa một dạng tệp chung đƣợc gọi là Resource Interchange File Format (RIFF). Tệp Riff đƣợc tổ chức nhƣ một tập các khúc gài vào nhau. Và hai biến dạng chung là: tệp Wave (hay Wav) lƣu trữ âm thanh; và tệp AVI lƣu trữ các hình ảnh video.
Đặc tính chung của các tệp Riff và Iff
Do tệp Wave là một dạng đặc biệt của tệp Riff, nên trƣớc hết ta nói về những đặc trƣng cơ bản cơ bản của dạng RIFF. Trong đó ta chú tâm tới các biến thể IFF khác, bao gồm Aiff và IFF/8SVX.
Một tệp Riff bao gồm một tập hợp các khúc xếp chồng. Mỗi khúc chứa một mã độ dài 4 ký tự (như RIFF, fmt, hay LIST; các mã ngắn hơn được chèn thêm các khoảng trống). Mã này chỉ định khuôn dạng của khúc. Ví dụ, một khúc fmt chứa các thông tin về khuôn dạng âm thanh. Tiếp theo đó là dạng khúc với một giá trị kích thƣớc 4-byte, chỉ ra kích thƣớc của dữ liệu đƣợc khúc đó mang theo. Trƣờng kích thƣớc trong khúc RIFF ít hơn kích thƣớc tệp tổng thể 8-bytes do không tính đến dạng khúc và kích thƣớc.
Một vài dạng khúc, nhƣ các khúc RIFF và LIST, đƣợc gọi là các “container chunks” mà chúng chứa đựng các khúc khác. Dữ liệu của "container chunk" bắt đầu với một mã độ dài 4 ký tự chỉ ra dạng của dữ liệu chứa trong khúc đó. Ví dụ, khúc RIFF trong minh hoạ trên có mã là WAVE, chỉ ra rằng nó chứa các dữ liệu về âm thanh. Các tên khúc bên trong có thể có nghĩa khác nhau, phụ thuộc vào các container xung quanh. Do khúc fmt đƣợc chứa trong RIFF Wave container, nên nó chỉ định khuôn dạng của dữ liệu âm thanh. Trong một dạng container khác, nó có thể chứa các thông tin khác.
Cấu trúc tổng quát của một tệp Wave
Đây là khuôn dạng phổ biến nhất để lƣu trữ âm thanh số trong thế giới PC. Nó đƣợc thiết kế cho các ứng dụng multimedia chạy dƣới Microsft Windows. Tệp Wav lƣu giữ các mẫu dạng sóng của một hoặc nhiều kênh theo các tần số lấy mẫu. Tệp Wav tự mã hoá và mô tả dữ liệu của nó trong phần mềm mà ta sử dụng. Nó không giới hạn độ dài tệp, có thể lên tới 4GB.
Một tệp Wave là một dạng đặc biệt của tệp Riff, và mọi tệp Riff đều bắt đầu với các ký tự RIFF. Tiếp theo đó là 4-byte độ dài và mã định dạng. Tệp Wav theo cấu trúc RIFF (Microsoft’s Resouce Interchange File Format), nên cấu trúc gồm các phần nhỏ gọi là khúc (chunk). Có hai loại khúc đƣợc dùng trong tệp .Wav: khúc dữ liệu (data chunk), nhƣ một định danh biểu diễn độ dài và bản thân dữ liệu; và khúc định dạng (format chunk) chứa các dữ liệu mô tả thông tin trong nó. Khuôn dạng chung tệp Wave nhƣ sau:
R I F F K Ý c h th - í c W A V E K h ó c f m t K h ó c d a t a
C ¸ c b y te s k Ýc h th - í c
Hình 2.3: Khuôn dạng tệp Wave
Do có rất nhiều tệp Wave có cùng cấu trúc cơ sở này, nên nhiều chƣơng trình xử lý các tệp Wave giống nhƣ chúng có một header ấn định. Điều này tạo thuận lợi cho việc viết các tệp Wave dài nhƣ khi chỉ viết các dữ liệu PCM và thiết lập một cách thích đáng các trƣờng kích thƣớc. Sau đây là mô tả dạng tệp Wave cơ bản:
Kích thƣớc Mô tả
4 Dạng khúc: RIFF
4 Kích thƣớc tệp tổng thể trừ 8 4 Dạng RIFF container: WAVE 4 Dạng khúc: fmt
4 Độ dài dữ liệu khúc định dạng: thông thƣờng là 16 16 Dữ liệu khúc định dạng
4 Dạng khúc: data
4 Độ dài dữ liệu âm thanh n Các mẫu âm thanh hiện thời
Tệp Wave có thể có các khúc khác trong chúng. Đặc biệt, khúc dữ liệu đơn đôi khi đƣợc thay thế bằng bởi một LIST container mà nó chứa các khúc slnt (chỉ ra các quãng trầm) và các khúc dữ liệu với các dữ liệu âm thanh.
Đọc tệp Wave
Trong dạng IFF gốc, cần thấy rõ rằng các khúc khác nhau có thể xuất hiện theo bất cứ thứ tự nào. Vì vậy, rất có thể một vài dạng tệp Wave có thể có khúc dữ liệu âm thanh trƣớc khúc định dạng. Và, sự thể hiện của bất kỳ khúc nào đều phụ thuộc vào cả dạng của khúc và dạng của container kèm theo. Nguyên tắc chung của RIFF và các dạng tƣơng tự là nên bỏ qua bất cứ khúc nào mà ta không thể nhận dạng đƣợc.
Một cách để truy cập những tệp nhƣ vậy là đọc lƣớt toàn bộ tệp và tạo ra một sự ánh xạ trong bộ nhớ với sự định vị và dạng của mỗi khúc. Sau đó, có thể định vị các khúc một cách riêng biệt tuỳ theo yêu cầu. Tuy nhiên, sự tiếp cận này, mặc dù chi tiết, nhƣng lại có một trở ngại lớn: nó yêu cầu phải có sự hiệu lực toàn bộ tệp ngay lập tức. Đặc biệt, nếu ta quan tâm tới quá trình truyền một tệp Wave qua mạng và quá trình phát nó giống nhƣ dữ liệu đƣợc nhận, ta có thể bỏ qua toàn bộ tệp và định vị các khúc trƣớc khi ta bắt đầu phát.
Ngoài ra, có một cách tiếp cận khác, thay vào việc ánh xạ sự định vị cho mỗi khúc, ta có thể đọc tệp từ phần đầu cho tới cuối và xử lý các khối ngay trong quá trình đọc.
Và, trong các tệp Riff (như trong mọi dạng IFF-derived file), mỗi khúc chiếm giữ một số bytes trong tệp. Nếu kích thƣớc của khúc hiện thời là lẻ, thì sẽ có một byte phụ của phần thêm vào cần đƣợc bỏ qua. Và có thể, khúc mà chúng ta vừa xoá lại là khúc cuối cùng của container của nó. Do đó, nếu bất cứ container còn lại ít hơn 8-bytes thì cần phải đƣợc kết thúc bởi vì một header của khúc yêu cầu ít nhất 8 bytes.
Khúc fmt
Khúc fmt chứa thông tin định dạng âm thanh hiện thời. Những nội dung chính xác của sự thay đổi khúc fmt phụ thuộc vào phƣơng thức nén. Bảng sau chỉ ra khuôn dạng khúc fmt sử dụng cho dữ liệu PCM.
Kích thƣớc Mô tả
2 Mã phƣơng thức nén 2 Số kênh truyền
4 Số mẫu trong mỗi giây
4 Số bytes trung bình trong mỗi giây 2 Block alignement
2 Số bits cho mỗi mẫu
2 Số bytes của thông tin thêm vào n Thông tin về bộ nén phụ
Mã hoá dữ liệu
Gần 100 bộ mã về phƣơng thức nén đã đƣợc đăng ký với Microsoft cho việc sử dụng trong các tệp Wave. Tệp Wave có thể sử dụng các phƣơng thức nén -Law hay A-Law. Sau đây là một vài khuôn dạng:
Mã hoá Mô tả 0 Không nhận dạng đƣợc 1 PCM 2 Microsoft ADPCM 6 ITU G.711 A-Law 7 ITU G.711 -Law 17 IMA ADPCM 20 ITU G.723 ADPCM 49 GSM 6.10 64 ITU G.721 ADPCM 80 MPEG 65535 Experiment
Tuy nhiên, tốt nhất nên sử dụng các bản tin dạng văn bản hơn là một số mã hoá. Nên đôi khi một phƣơng thức nén tối ƣu hay phổ biến cũng không nên sử dụng (ví dụ như phương thức nén MS ADPCM).
Khúc dữ liệu
Khúc dữ liệu (Data chunk) của dạng Wav theo chuẩn mẫu RIFF. Bốn byte đầu xác định khúc dữ liệu với các ký tự “data” trong mã ASCII. Theo sau là bốn byte biểu diễn độ dài dữ liệu. Cuối cùng là các dữ liệu đƣợc mã hoá trong một số byte cho trƣớc.
Các khúc văn bản
Sự thay đổi của các khúc tạo ra sự sinh động dạng văn bản. Các khúc này có thể xuất hiện trong bất cứ dạng tệp Riff nào, chứ không phải chỉ trong các tệp Wave. Tên của chúng đều bắt đầu với một chữ "I" để chỉ ra rằng chúng đƣợc dùng cho việc lƣu trữ thông tin.
2.1.3.2 Tệp Midi. (*.mid)
Một tệp MIDI là một chuỗi các khúc. Các khúc này có cùng một khuôn dạng chung giống nhƣ các khúc đƣợc sử dụng trong các tệp Aiff, Iff, và Wave. Mỗi khúc có 4 ký tự phân loại, một mã độ dài kích thƣớc 4-byte (trong khuôn dạng MSB), và một vài dữ liệu. Tuy nhiên, khác với các khuôn dạng khác, các khúc MIDI không xếp chồng.
Hiện nay, chỉ có 2 loại khúc. Khúc MThd chứa thông tin về header nói chung; và khúc MTrk chứa một rãnh đơn. Khúc MThd xuất hiện tại phần đầu của mọi tệp MIDI, và đây là dấu hiệu để định danh một tệp MIDI chuẩn.
Khúc MIDI Header
Khúc MThd chứa một chút các sự kiện cơ sở về tệp MIDI. Mọi giá trị này đƣợc lƣu trữ trong khuôn dạng MSB. Sau đây là nội dung của khúc MIDI MThd:
Bytes Mô tả
2 Dạng tệp 2 Số các rãnh
2 Khuôn dạng thời gian
Có 3 loại tệp MIDI, chúng đƣợc phân loại tuỳ theo cách xử lý các rãnh:
· Tệp dạng 0 chỉ chứa duy nhất một rãnh. Một cách rõ ràng, đây là tệp dễ nhất để có thể phát, nên đây là dạng thông dụng cho các tệp quảng cáo. · Tệp dạng 1 chứa rất nhiều rãnh mà chúng đƣợc phát một cách đồng thời.
Một chƣơng trình dùng để phát các tệp dạng 1 phải bằng cách nào đó san phẳng dữ liệu thành các dòng sự kiện đơn trƣớc khi phát.
· Tệp dạng 2 chứa nhiều rãnh nhƣng không thừa nhận bất cứ sự liên hệ nào giữa các rãnh. Nói chung, các tệp dạng 2 là không phổ biến.
Các rãnh MIDI
Chú ý rằng một rãnh là khác so với một kênh MIDI. Mặc dù đây là dạng chung cho các tệp multi-track để có thể phát mỗi rãnh trên một kênh khác nhau, và trong quá trình tổ hợp một bản nhạc có thể sử dụng số các rãnh tuỳ ý để có thể phát các rãnh trên các kênh khác nhau theo bất cứ kiểu mẫu nào.
Mỗi rãnh MIDI là một danh sách các sự kiện, mà mỗi sự kiện có một “delta time” đặt trƣớc. Mỗi khúc trong một tệp MIDI có một độ dài đã đƣợc ấn định, nên cần thận trọng khi rãnh hoá số các bytes đƣợc đọc để ta có thể biết khi nào dữ liệu rãnh kết thúc. Nếu đây không phải rãnh đầu tiên, thì cần phải đảm bảo rằng các sự kiện mới đã hoàn toàn đƣợc chèn vào trong bộ nhớ danh sách các sự kiện.
Giống nhƣ bất kỳ danh sách mã chèn nào, quá trình chèn một sự kiện MIDI yêu cầu hai trƣờng hợp sau: một, nếu sự kiện vào phần đầu của danh sách (trong trường hợp này cần phải cập nhật đầu đọc danh sách); hai, nếu sự kiện vào giữa danh sách (trong trường hợp này một container trỏ khác nhận sự cập nhật).
Điều này làm tăng sự phức tạp bởi sự cần thiết chèn nó vào tại vị trí tạm thời chính xác và điều chỉnh các độ trễ một cách thích hợp. Ngoài ra, để duy trì không gian, các tệp MIDI sử dụng các số nguyên biến độ dài để lƣu trữ các “delta times” và các giá trị tới hạn khác. Điều này cho phép các giá trị nhỏ (như giá trị 0) có thể đƣợc lƣu trữ trong một byte đơn đồng thời cho phép các giá trị đạt tới 32 bits.
Delta times
Các sự kiện MIDI xuất hiện tại một số thời điểm xác định. Có 2 cách để đánh dấu các thông tin này:
·Lƣu trữ thời gian tuyệt đối tại mỗi thời điểm mà sự kiện xuất hiện, hay có thể lƣu trữ các quãng thời gian giữa các sự kiện.
·Mỗi sự kiện đƣợc đặt trƣớc bởi một số chỉ ra số các ticks để tách biệt nó với sự kiện trƣớc đó. Khoảng tồn tại chính xác của một tick phụ thuộc vào khuôn dạng thời gian đã đƣợc ấn định trong header, và cũng có thể đƣợc thay đổi bởi các sự kiện riêng biệt trong tệp.
Các sự kiện MIDI
Một sự kiện MIDI là một gói các dữ liệu mà nó chỉ rõ một số các sự kiện âm nhạc, nhƣ việc nhấn và nhả phím. Byte đầu tiên của gói là byte trạng thái, mà nó định rõ dạng của sự kiện, và đôi khi, là kênh truyền. Các bytes trạng thái thƣờng xuyên có thiết lập bit cao. Còn lại là các byte dữ liệu, mà chúng không bao giờ có thiết lập bit cao. Sự phân biệt này là rất quan trọng.
Theo cách chung, các kênh truyền MIDI đƣợc đánh số từ 1 tới 16, và các nhạc cụ MIDI là từ 1 tới 128. Tuy nhiên, các mã hoá số xắp hàng từ 0 tới 15 và 0 tới 127 một cách tƣơng ứng. Ta sẽ thêm hay bớt 1 khi chuyển đổi giữa các mã số hoá và ngôn ngữ MIDI.
Running Status
Để tạo "wire protocol" thêm hiệu quả, MIDI sử dụng một kỹ thuật gọi là “running status”, kỹ thuật này bỏ qua các bytes trạng thái lặp. Khi đọc một tệp MIDI, nếu gặp một byte dữ liệu, trong khi ta đang cần một byte trạng thái, thì ta dùng lại trạng thái trƣớc đó. Để tạo cho kỹ thuật này thêm hữu hiệu, có một quy ƣớc rằng một “note-on event” với một vận tốc (velocity) thiết lập về 0 cũng giống nhƣ một “note-off event” với một vận tốc ngầm định là 64. Nhƣ vậy, một dẫy dài các notes trên một kênh truyền đơn có thể đƣợc kiểm soát với chỉ 2 bytes cho mỗi sự kiện.
Quản lý các sự kiện MIDI
Các tệp MIDI thƣờng đƣợc lƣu trữ nhƣ các rãnh đơn. Mặc dù các sự kiện trong mỗi rãnh đƣợc lƣu trữ theo thứ tự tạm thời, luồng sự kiện mà nó nhận đƣợc để phát là một tổ hợp của các rãnh này. Hơn nữa, các sự kiện trong mỗi rãnh (như những sự thay đổi về nhịp độ) tác động lên quá trình phát lại của các sự kiện trong các rãnh khác.
Cho các tệp dạng 1, cần phải đọc mọi sự kiện vào bộ nhớ trƣớc khi phát chúng. Để đạt đƣợc điều này, cần lƣu trữ một danh sách liên kết đơn của các sự kiện MIDI.
Phần lớn các sự kiện gồm một byte trạng thái và một cặp byte dữ liệu. Và cũng cần phải lƣu trữ giá trị độ trễ và số rãnh mà sự kiện này xuất hiện. Vài sự kiện MIDI riêng biệt có thể chứa một lƣợng tuỳ ý các dữ liệu, nên cần thêm một cấu trúc phụ để nắm giữ dữ liệu đó khi cần đến. Phần lớn các sự kiện MIDI có độ dài cố định. Ví dụ nhƣ một “note-on event” có 2 bytes dữ liệu tiếp theo các bytes trạng thái.
Khuôn dạng MIDI
Khuôn dạng MID là các tệp điều khiển âm thanh trong multimedia. MIDI là một hệ thống hoàn chỉnh không chỉ có khuôn dạng xác định mà còn có các tín hiệu và hệ thống phần cứng.
Các tệp MIDI lƣu giữ một dòng các lệnh cho các hệ thống tổng hợp (synthesizer) MIDI. Các tệp đƣợc xây dựng từ các khúc (chunks). Có hai loại khúc:
header chunk và track chunk. Mỗi tệp MIDI gồm một header chunk và một hoặc nhiều track chunk.
Mỗi khúc có 4 byte để nhận dạng. Các dấu hiệu theo sau 4 byte xác định độ dài dữ liệu trong khúc (không kể 8 byte dữ liệu mô tả), cho phép một khúc dài 4GB.