GIAO DIỆN

Một phần của tài liệu luận văn phương pháp mã hoá và nén âm thanh theo chuẩn mpeg, từ đó dựa trên một số source code (viết bằng c) viết lại bằng ngôn ngữ visual c++ (Trang 68 - 79)

Dựa trên sơ đồ khối và lưu đồ giải thuật. Giao diện bao gồm các phần như hình vẽ sau:

1. Input group.

Nhĩm các thơng tin cấu hình và lệnh về tập tin nguồn ( *.wav). Bao gồm các

1 2 3 4 5 6 7 8 2 9 10 11 12 13 14

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

2. Open button.

Mở hộp thoại File Open của Windows để chọn file cần nén. Phần mở rộng mặc định là .wav

3. Text Edit box.

Dùng gõ file nguồn bằng tay. Mặc định là *.wav. 4. Bitrates.

Cho biết chỉ số tốc độ bit của tập tin nguồn .wav đã chọn trên mục 2 hoặc 3. Chỉ số mặc định là 128. Khơng sửa bằng tay được.

5. Samplerates.

Cho biết tần số lấy mẫu của tập tin nguồn .wav đã chọn trên mục 2 hoặc 3. Tần số mặc định là 44100 Hz. Khơng sửa bằng tay được.

Các tần số cĩ thể bao gồm : 32000, 44100 và 48000 Hz. 6. Output.

Nhĩm các thơng tin cấu hình và lệnh về tập tin đích ( *.mp3). Bao gồm các thơng tin như : bitrates, samplerates, mode, File path name..

7. Save button.

Mở hộp thoại File Save của Windows để ghi đường dẫn và tên file nén. Phần mở rộng mặc định là .mp3.

8. Text Edit box.

Dùng gõ đường dẫn à tên tập tin đích bằng tay. Mặc định là *.mp3.

Khi đã chọn được tập tin nguồn trong phần 2 hoặc 3 thì trong ơ này sẽ tự động xuất hiện đường dẫn và tên tập tin đích.

9. Bitrates.

Định chỉ số tốc độ bit của tập tin đích đã chọn trên mục 7 hoặc 8. Chỉ số mặc định là 128. Cĩ thể chọn các chỉ số khác trong ơ kéo xuống, bao gồm các giá trị : 16, 32, 40, 48, 56, 64, 80, 96, 112, 128, 156, 160, 192, 224, 256, 320.

10. Samplerates.

Cho biết tần số lấy mẫu của tập tin đích, phụ thuộc và bằng với tần số lấy mẫu của tập tin nguồn. Tần số mặc định là 44100 Hz. Khơng sửa bằng tay được. 11. Mode group.

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

Nhĩm các chế độ Stereo hay Mono. Mặc định là Stereo. 12. Progress bar.

Thanh tiến trình, xuất hiện trong quá trình nén từ tập tin nguồn .wav sang tập tin đích .mp3 .

13. Compress button.

Nút nhấn này chỉ cĩ thể sau khi đã chọn và định cấu hình đầy đủ cho các tập tin nguồn và đích. Nghĩa là chỉ cĩ thể nhấn được nút này sau khi đã nhấn nút Update.

Khi nhấn nút này, quá trình nén từ tập tin nguồn sang tập tin đích mới thực sự bắt đầu. Đồng thời thanh tiến trình mới bắt đầu hoạt động.

Kết thúc quá trình nén sẽ cĩ thơng điệp báo cho biết đã hồn tất cơng việc 14. Update button.

Phím này được nhấn sau khi đã chọn các tập tin nguồn và đích để cập nhật các thơng số chuẩn bị cho quá trình nén và kích hoạt phím Compress. (adsbygoogle = window.adsbygoogle || []).push({});

III. Chương trình.

Chương trình cĩ nền là hộp thoại MP3 COMPRESSOR hiển thị các phím nhấn cho người sử dụng lựa chọn và chạy ứng dụng. Do đĩ, tất cả các hàm chính đều được đặt trong lớp CMp3Dlg.

Sau đây ta sẽ lần lược khảo sát một số hàm quan trọng. 1. OnInitDialog( ) :

Hàm này khởi tạo một số giá trị mặc định cho hộp thoại, nhằm giúp cho người sử dụng cĩ một cái nhìn tồn cục và hiểu được ngay ứng dụng, để từ đĩ cĩ thể chọn lựa các thơng số thích hợp cho ứng dụng.

Đồng thời, cũng cài đặt sẵn một số giá trị ban đầu cho các đối tượng được dùng cho chương trình.

BOOL CMp3Dlg::OnInitDialog() {

CDialog::OnInitDialog(); ...

// Khởi tạo giá trị ban đầu cho hộp thoại

m_stereo_in = 0;

m_stereo_out = 0;

m_file_in = "*.wav";

m_file_out = "*.mp3";

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình m_bitrates_in = "128"; m_bitrates_out.AddString("32"); m_bitrates_out.AddString("40"); m_bitrates_out.AddString("48"); m_bitrates_out.AddString("56"); m_bitrates_out.AddString("64"); m_bitrates_out.AddString("80"); m_bitrates_out.AddString("96"); m_bitrates_out.AddString("112"); m_bitrates_out.AddString("128"); m_bitrates_out.AddString("160"); m_bitrates_out.AddString("192"); m_bitrates_out.AddString("224"); m_bitrates_out.AddString("256"); m_bitrates_out.AddString("320"); m_bitrates_out.SetCurSel(8); UpdateData(FALSE); bOpen = FALSE; bSave = FALSE;

// Gán các hằng cho các đối tượng

config.mpeg.type = TYPE_MPEG_I; config.mpeg.layr = LAYR_III; config.mpeg.mode = MODE_STEREO; config.mpeg.bitr = 128; config.mpeg.psyc = PSYC_ATT; config.mpeg.emph = EMPH_NONE; config.mpeg.crc = 0; config.mpeg.ext = 0; config.mpeg.mode_ext = 0; config.mpeg.copyright = 0; config.mpeg.original = 0; GetDlgItem(IDC_COMPRESS)->EnableWindow(FALSE); m_pbar.SetRange(0, 10000); ...

return TRUE; // return TRUE unless you set the focus to a control }

2. OnFileOpen( ) :

Hàm mở hộp thoại Open của Windows để chọn file nguồn cĩ phần mở rộng mặc định là .wav, gán cho biến m_file_in đường dẫn và tên file đã chọn.

Đồng thời cũng tạo đường dẫn và tên file mặc định cho tập tin đích cĩ phần mở rộng .mp3 và gán cho biến m_file_out.

void CMp3Dlg::OnFileOpen() {

// Mở hộp thoại File Open của Windows bằng hàm thành viên dlgOpen của

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

CFileDialog dlgOpen(TRUE, "wav", "*.wav"); if (dlgOpen.DoModal() == IDOK) {

m_file_in = dlgOpen.GetPathName(); // gán đường dẫn file nguồn

// cho đối tượng m_file_in

int len;

str1 = m_file_in; len = str1.GetLength(); str2 = str1.Left(len - 3); str2 += "mp3";

m_file_out = str2; // gán đường dẫn file đích

// cho đối tượng m_file_out

bOpen = TRUE; UpdateData(FALSE); } (adsbygoogle = window.adsbygoogle || []).push({});

}

3. OnFileWrite( ) :

Hàm mở hộp thoại Save của Windows để chọn đường dẫn và tên tập tin đích trong trường hợp khơng muốn đường dẫn và tên file mặc định do hàm OnFileOpen( ) tạo ra, và gán nĩ cho biến m_file_out.

void CMp3Dlg::OnFileWrite() {

CFileDialog dlgWrite(FALSE, "mp3", str2); if (dlgWrite.DoModal() == IDOK) {

m_file_out = dlgWrite.GetPathName(); // gán đường dẫn file đích

// cho đối tượng m_file_out

UpdateData(FALSE); bSave = TRUE; }

}

4. OnUpdate( ) :

Hàm cập nhật tất cả các thơng số đã chọn trên hộp thoại, đưa vào các đối tượng được dùng trong chương trình. Đồng thời kích hoạt phím nhấn COMPRESS cho phép phím này đã cĩ thể bắt đầu được sử dụng.

Nếu các thơng số nhập khơng hợp lệ sẽ cho hiện ra các thơng báo để nhập lại.

void CMp3Dlg::OnUpdate( ) {

UpdateData(TRUE);

if (!m_file_in.Compare("*.wav"))

MessageBox("Enter the Input file, please!"); else

if (!m_file_out.Compare("*.mp3")) { int len;

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình len = str1.GetLength(); str2 = str1.Left(len - 3); str2 += "mp3"; m_file_out = str2; }

config.infile = m_file_in.GetBuffer(5); // Chuyển giao con trỏ chỉ

// đến file nguồn

if (!wave_open()) {

MessageBox("Unable to open input file..."); bWaveOpen = FALSE;

} else

bWaveOpen = TRUE;

// Gán giá trị cấu hình bitrates cho biến config.mpeg.bitr tuỳ theo giá trị đã // chọn trên hộp thoại. if (m_bitrates_out.GetCurSel()==0) config.mpeg.bitr = 32; if (m_bitrates_out.GetCurSel()==1) config.mpeg.bitr = 40; if (m_bitrates_out.GetCurSel()==2) config.mpeg.bitr = 48; if (m_bitrates_out.GetCurSel()==3) config.mpeg.bitr = 56; if (m_bitrates_out.GetCurSel()==4) config.mpeg.bitr = 64; if (m_bitrates_out.GetCurSel()==5) config.mpeg.bitr = 80; if (m_bitrates_out.GetCurSel()==6) config.mpeg.bitr = 96; if (m_bitrates_out.GetCurSel()==7) config.mpeg.bitr = 112; if (m_bitrates_out.GetCurSel()==8) config.mpeg.bitr = 128;

if (m_bitrates_out.GetCurSel()==9) config .mpeg.bitr= 160;

if (m_bitrates_out.GetCurSel()==10) config.mpeg.bitr = 192; if (m_bitrates_out.GetCurSel()==11) config.mpeg.bitr = 224; if (m_bitrates_out.GetCurSel()==12) config.mpeg.bitr = 256; if (m_bitrates_out.GetCurSel()==13) config.mpeg.bitr = 320; config.mpeg.bitrate_index = find_bitrate_index(config.mpeg.bitr); bOpen = FALSE; bSave = FALSE;

// Hàm GetDlgItem(IDC_ ) cho phép phím nhấn cĩ IDC_ làm thơng số cĩ thể

// hoạt động được

if (bWaveOpen) GetDlgItem(IDC_COMPRESS)->EnableWindow(); UpdateData(FALSE); (adsbygoogle = window.adsbygoogle || []).push({});

}

5. OnCompress( ) :

Khi gọi hàm này, quá trình nén từ tập tin nguồn .wav sang tập tin đích .mp3 sẽ bắt đầu thực hiện.

Kết thúc quá trình nén sẽ cĩ hộp thoại xuất hiện thơng báo đã hồn tất. void CMp3Dlg::OnCompress() { CCompressDlg compDlg; config.outfile = m_file_out.GetBuffer(5); L3_compress(); wave_close();

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

// cơng việc nén đã hồn tất

m_pbar.SetPos(0); // Trả trạng thái thanh tiến trình về vị trí đầu

GetDlgItem(IDC_COMPRESS)->EnableWindow(FALSE); }

6. Wave_open( ) :

Hàm mở file nguồn và kiểm tra xem định dạng file cĩ hợp lệ khơng, nếu khơng thì sẽ hiện thơng bào và chọn lại file khác.

bool CMp3Dlg::wave_open() {

static char *channel_mappings[] = {NULL,"mono","stereo"}; unsigned short wFormatTag;

unsigned long dAvgBytesPerSec; unsigned short wBlockAlign; long filesize; long header_size;

if((config.wave.file = fopen(config.infile,"rb")) == NULL) { MessageBox("Unable to open file");

return false; }

if(!checkString(config.wave.file,"RIFF")) {

MessageBox("Input not a MS-RIFF file"); return false;

}

filesize = Read32BitsLowHigh(config.wave.file); // complete wave chunk size

if(!checkString(config.wave.file,"WAVE")) { MessageBox("Input not WAVE audio"); return false;

}

/* WAVE FMT format chunk */

if(!checkString(config.wave.file,"fmt ")) { MessageBox("Can't find format chunk"); return false;

}

/* my total header size calculations don't work, so this is bogus... */ header_size = Read32BitsLowHigh(config.wave.file); /* chunk size */ wFormatTag = Read16BitsLowHigh(config.wave.file);

if(wFormatTag!=0x0001) {

MessageBox("Unknown WAVE format"); return false;

}

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình config.wave.samplerate = Read32BitsLowHigh(config.wave.file); dAvgBytesPerSec = Read32BitsLowHigh(config.wave.file); wBlockAlign = Read16BitsLowHigh(config.wave.file); /* PCM specific */ if(config.wave.channels>2) {

MessageBox("More than 2 channels\n"); return false; } if(config.wave.channels>1) { m_stereo_in = 0; m_stereo_out = 0; config.mpeg.mode = MODE_STEREO; MessageBox("WAVE audio, mode stereo"); } (adsbygoogle = window.adsbygoogle || []).push({});

else {

m_stereo_in = 1; m_stereo_out = 1;

config.mpeg.mode = MODE_MONO;

MessageBox("Microsoft RIFF , WAVE audio, mode mono"); } switch (config.wave.samplerate) { case 32000: m_samplerates_in = "32000"; m_samplerates_out = "32000"; config.mpeg.samplerate_index = 2; break; case 44100: m_samplerates_in = "44100"; m_samplerates_out = "44100"; config.mpeg.samplerate_index = 0; break; case 48000: m_samplerates_in = "48000"; m_samplerates_out = "48000"; config.mpeg.samplerate_index = 1; break;

default: MessageBox("Samplerate not supported !!"); exit(-1); } config.wave.bits = Read16BitsLowHigh(config.wave.file); if(config.wave.bits!=16) { MessageBox("NOT 16 Bit !!!"); return false; } if(!checkString(config.wave.file,"data")) { MessageBox("Can't find data chunk"); return false;

}

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

filesize = ftell(config.wave.file);

fseek(config.wave.file, header_size, SEEK_SET);

config.wave.total_samples =(filesize-header_size)/(2*config.wave.channels); config.wave.length = config.wave.total_samples/config.wave.samplerate; return true;

}

7. L3_compress( ) :

Đây là hàm quan trọng nhất trong chương trình, nĩ mơ tả toàn bộ giải thuật của ứng dụng. Vịng lặp nén cũng nằm trong hàm này. Mỗi vịng lặp thực hiện cơng việc nén cho một frame dữ liệu đọc từ file nguồn. Cũng từ vịng lặp này, ta cho thanh tiến trình hoạt động nhờ vào kích thước biết trước của file đọc vào. Vịng lặp kết thúc cũng là lúc thanh tiến trình được điền đầy và thơng báo “Compress complete !” xuất hiện. void CMp3Dlg::L3_compress()

{

int frames_processed;

int m_step;

int total_frames;

static short buffer[2][1152]; int channel; int i; int gr; short sam[2][1344]; double snr32[32]; L3_psy_ratio_t ratio; double pe[2][2]; L3_side_info_t side_info; short *buffer_window[2]; double win_que[2][HAN_SIZE]; double l3_sb_sample[2][3][18][SBLIMIT]; double mdct_freq[2][2][576]; int l3_enc[2][2][576]; L3_scalefac_t scalefactor; bitstream_t bs; double vg_slots_per_frame; ouble rac_slots_per_frame; ong hole_slots_per_frame; ouble lot_lag; nt mean_bits; unsigned long sent_bits = 0; unsigned long frame_bits = 0; int sideinfo_len; // Mở thiết bị để ghi vào

open_bit_stream_w(&bs, config.outfile, BUFFER_SIZE);

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình memset((char *)&side_info,0,sizeof(L3_side_info_t)); L3_psycho_initialise(); L3_subband_initialise(); L3_mdct_initialise(); L3_loop_initialise(); config.mpeg.mode_gr = 2; config.mpeg.samples_per_frame = 1152; config.mpeg.total_frames = config.wave.total_samples/config.mpeg.samples_per_frame; total_frames = config.mpeg.total_frames; config.mpeg.bits_per_slot = 8; frames_processed = 0; sideinfo_len = 32; if(config.wave.channels==1) sideinfo_len += 136; else sideinfo_len += 256; if(config.mpeg.crc) sideinfo_len += 16;

/* Figure average number of 'slots' per frame. */

avg_slots_per_frame = ((double)config.mpeg.samples_per_frame / ((double)config.wave.samplerate/1000)) * ((double)config.mpeg.bitr / (double)config.mpeg.bits_per_slot); whole_slots_per_frame = (int)avg_slots_per_frame; frac_slots_per_frame = avg_slots_per_frame - (double)whole_slots_per_frame; slot_lag = -frac_slots_per_frame; if(frac_slots_per_frame==0) config.mpeg.padding = 0; while(wave_get(buffer)) { frames_processed++;

m_step = (int)(10000 * frames_processed / total_frames); m_pbar.SetPos(m_step);

buffer_window[0] = buffer[0]; buffer_window[1] = buffer[1]; if(frac_slots_per_frame!=0)

if(slot_lag>(frac_slots_per_frame-1.0)) { /* No padding for this frame */ slot_lag -= frac_slots_per_frame; config.mpeg.padding = 0;

} else

{ /* Padding for this frame */

slot_lag += (1-frac_slots_per_frame); config.mpeg.padding = 1;

}

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình (adsbygoogle = window.adsbygoogle || []).push({});

mean_bits = (config.mpeg.bits_per_frame - sideinfo_len) /

config.mpeg.mode_gr; /* psychoacousic model */ for(gr=0;gr<config.mpeg.mode_gr;gr++) for(channel=0;channel<config.wave.channels;channel++) L3_psycho_analize(channel, &buffer[channel][gr*576], &sam[channel][0], &snr32[0], &ratio.l[gr][channel][0], &ratio.s[gr][channel][0], &pe[gr][channel], &side_info.gr[gr].ch[channel].tt); /* polyphase filtering */ for(gr=0;gr<config.mpeg.mode_gr;gr++) for(channel=0;channel<config.wave.channels;channel++) for(i=0;i<18;i++) { L3_window_subband(&buffer_window[channel], &win_que[channel][0], channel); L3_filter_subband(&win_que[channel][0], &l3_sb_sample[channel][gr+1][i][0]); }

/* apply mdct to the polyphase output */

L3_mdct_sub(l3_sb_sample, mdct_freq, &side_info, &config); /* bit and noise allocation */

L3_iteration_loop(pe,mdct_freq,&ratio,&side_info, l3_enc, mean_bits,&scalefactor, &config); /* write the frame to the bitstream */

L3_format_bitstream(l3_enc, &side_info, &scalefactor, &bs, mdct_freq, NULL , 0, &config); frame_bits = sstell(&bs) - sent_bits;

sent_bits += frame_bits; }

L3_FlushBitstream(); close_bit_stream_w(&bs); }

Khoa CNTT – ĐHBKHN GVHD Thầy:Dư Thanh Bình

Tài liệu tham khảo

1. Giáo trình âm học Kiến trúc.

KTS. Việt Hà - Nguyễn Ngọc Giả

Trường Đại học kiến trúc – 1993

2. Kỹ năng lập trình Windows bằng Visual C++6.

Lê Minh Trí

Nhà xuất bản thanh niên – 2001 (Tập 1&2)

3. Xử lý tín hiệu số.

Quách Tuấn Ngọc

Nhà xuất bản Giáo dục – 1997 4. Digital Signal Processing

John G.Proakis - Dimitris G.Manolakis Prentice Hall

5. C Language Algorithms for Digital Signal Processing Paul M.Embree - Bruce Kimble Prentice Hall

Một phần của tài liệu luận văn phương pháp mã hoá và nén âm thanh theo chuẩn mpeg, từ đó dựa trên một số source code (viết bằng c) viết lại bằng ngôn ngữ visual c++ (Trang 68 - 79)