МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ "ЛЬВІВСЬКА ПОЛІТЕХНІКА"
ІНСТИТУТ КОМП’ЮТЕРНИХ ТЕХНОЛОГІЙ, АВТОМАТИКИ ТА МЕТРОЛОГІЇ
КАФЕДРА ”ЗАХИСТ ІНФОРМАЦІЇ”
Розрахункова робота
з курсу: "Системи запису та відтворення інформації"
на тему: “РОЗРОБЛЕННЯ ЦИФРОВОГО ДИКТОФОНУ”
Варіант – 10
Виконав:
студент гр. ЗІ-31
Перевірив:
Львів – 2011р.
Мета роботи: Закріпити отримані теоретичні знання на практиці; розробити цифровий диктофон і отримати навички розробки пристроїв, які можна використовувати в системах запису і відтворення інформації.
Завдання:
Розробити принципову електричну схему цифрового диктофону згідно завдання.
Скласти специфікацію елементів схеми.
Навести всі необхідні розрахунки.
Навести АЧХ розрахованого мікрофонного підсилювача + фільтра.
Написати на мові MatLab або C функції запису файлу у MMC/SD-карту, на якій встановлена файлова система FAT16.
Написати на мові MatLab або C функцію запису файлу у wav-форматі.
Написати на мові MatLab або C функцію стиснення аудіосигналу з потрібною степінню компресії.
Завдання варіанту:
Варіант
Тип джерела живлення
Частота дискретизації, Гц
Степінь стиску
Час запису без стиску, год
Тип мікрофону
Мікрофонний підсилювач + фільтр
17
2хAAA
16000
7
300
MEMS
Варіант 2
Принципова електрична схема цифрового диктофону:
Розрахунки:
Розрахунок мікрофонного підсилювача + фільтра:
Чутливість мікрофона (типова) = -42дБ, і
;
;
Нехай звуковий тиск
Коефіцієнт підсилення схеми:
Розподілимо коефіцієнт підсилення між операційними підсилювачами:
тоді
Знайдемо номінали елементів схеми:
Розрахунок опору в колах світло діодів:
Розрахунок NAND-Flash пам’яті:
час запису = 600год;
кількість вибірок = 4000;
компресія = 2;
об’єм пам’яті =
АЧХ мікрофонного підсилювача + фільтра:
Програма запису файлу у MMC/SD-карту, на якій встановлена файлова система FAT16:
clear all;
% Кількість байт в секторі
BytesPerSec = 512;
% Буфер для читання/запису даних
Buffer = zeros(BytesPerSec, 1);
% 1. Переводимо карту в активний режим
s = MMC_SD_Init('D:\p\3-ИЙ КУРС\С-ми запису та відтворення інформації\Lab_5\SD_512\SD_512.bin');
% 2. Прочитати 0 сектор - VBR
% Номер сектора з якого починається VBR
VBR_Addr = 0;
LBA = 0;
[Buffer, c1] = MMC_SD_Read_Sector(s, LBA);
% Перевіряємо сигнатуру VBR
if (Buffer(511) ~= hex2dec('55') | Buffer(512) ~= hex2dec('AA'))
disp('VBR FAT Error');
return;
end;
% Визначаємо кількість байт в секторі
BytesPerSec = Buffer(hex2dec('b') + 1) + 2^8 * Buffer(hex2dec('b') + 2);
z = sprintf('Кількість байт в секторі: %d', BytesPerSec);
disp(z);
% Визначаємо кількість секторів в кластері
SecPerClus = Buffer(hex2dec('d') + 1) ;
z = sprintf('Кількість секторів в кластері: %d', SecPerClus);
disp(z);
% Кількість зарезервованих секторів від початку карти
RsvdSecCnt = Buffer(hex2dec('e') + 1) + 256 * Buffer(hex2dec('f') + 1);
z = sprintf('Кількість зарезервованих секторів від початку карти: %d', RsvdSecCnt);
disp(z);
% Кількість таблиць FAT
NumFATs = Buffer(hex2dec('10') + 1);
z = sprintf('Кількість таблиць FAT: %d' , NumFATs);
disp(z);
% Кількість записів в Root Directory
RootEntCnt = Buffer(hex2dec('11') + 1) + 256 * Buffer(hex2dec('12') + 1);
z = sprintf('Кількість записів в кореневому каталозі Root Directory: %d', RootEntCnt);
disp(z);
% Кількість секторів MMC/SD-карти (до 32 MB)
TotSec = Buffer(hex2dec('13') + 1) + 256 * Buffer(hex2dec('14') + 1);
if TotSec == 0
% MMC/SD-карта > 32 MB
TotSec = Buffer(hex2dec('20') + 1) + 256 * Buffer(hex2dec('21') + 1) + 2^16 * Buffer(hex2dec('22') + 1) + 2^24 * Buffer(hex2dec('23') + 1);
end;
z = sprintf('Загальна кількість секторів MMC/SD-карти: %d', TotSec);
disp(z);
% Розмір таблиці FAT у секторах
SecPerFAT = Buffer(hex2dec('16') + 1) + 256 * Buffer(hex2dec('17') + 1) ;
z = sprintf('Розмір таблиці FAT у секторах: %d', SecPerFAT);
disp(z);
if (Buffer(hex2dec('36') + 1) ~= 'F' & Buffer(hex2dec('37') + 1) ~= 'A' & Buffer(hex2dec('38') + 1) ~= 'T' & Buffer(hex2dec('39') + 1) ~= '1' & Buffer(hex2dec('ЗА') + 1) ~= '6')
disp('FAT16 Error');
end;
temp = Buffer((hex2dec('36') + 1):(hex2dec('3A') + 1));
z = sprintf('Тип файлової системи: %s', char(temp));
disp(z);
% Обчислюємо номер сектору з якого починається таблиця FAT1 та FAT2
FAT_Sect1 = VBR_Addr + RsvdSecCnt;
z = sprintf('Перший сектор FAT1: %d', FAT_Sect1);
disp(z);
if (NumFATs > 1)
FAT_Sect2 = FAT_Sect1 + SecPerFAT;
z = sprintf('Перший сектор FAT2: %d', FAT_Sect2);
disp(z) ;
end;
% Обчислюємо номер сектору з якого починається кореневий каталог Root Directory
RootDir_Sect = VBR_Addr + RsvdSecCnt + SecPerFAT * NumFATs;
z = sprintf('Перший сектор Root Directory: %d', RootDir_Sect);
disp(z);
% Обчислюємо кількість секторів в Root Directory
RootDir_SectCnt = RootEntCnt * 32 / BytesPerSec;
z = sprintf('Кількість секторів в Root Directory: %d', RootDir_SectCnt);
disp(z) ;
% Обчислюємо номер сектора початку області даних
Data_Sect = VBR_Addr + RsvdSecCnt + SecPerFAT * NumFATs + RootDir_SectCnt;
z = sprintf('Номер сектора початку області даних: %d', Data_Sect);
disp(z);
%//////////////// Шукаємо 1-ий вільний запис в RootDirectory /////////////
ByteCnt = 1; % початк запису в байтах
Flag_Free = 0; % прапорець знаходження вільного запису в RootDirectory
for jj = 1 : RootDir_SectCnt %від 1-го до останнього сектору RootDirectory
Buffer = MMC_SD_Read_Sector(s, RootDir_Sect + jj - 1); %читає поточний сектор
for ii = 1 : BytesPerSec/32 % лічильник записів
temp = Buffer(ByteCnt); % читає перший байт
if (temp == 0 | temp == hex2dec('E5'))
z = sprintf('Вільний запис знайдено');
disp(z);
Free_Sect_RootDir = RootDir_Sect + jj - 1;
z = sprintf('Сектор вільного запису в RootDirectory: %d', Free_Sect_RootDir);
disp(z);
Free_Num_RootDir = ii;
z = sprintf('Номер вільного запису: %d', Free_Num_RootDir);
disp(z);
Flag_Free = 1;
break;
end;
ByteCnt = ByteCnt + 32; %наступний запис (1 запис--32байти)
end;
if (Flag_Free == 1) %файл знайдено
break;
end;
ByteCnt = 1;
end;
if (Flag_Free == 0)
z = sprintf('Неможливо записати файл: немає вільної памяті');
disp(z);
return; %вихід з програми
end;
%//////////////// Запишемо ім'я файлу //////////////////////
Entry = Buffer(32*(ii-1) + 1 : 32*(ii-1) + 1 +31); %вільний запис в Root Directory
Entry(1) = 'M';
Entry(2) = 'Y';
Entry(3) = 'F';
Entry(4) = 'I';
Entry(5) = 'L';
Entry(6) = 'E';
Entry(7) = '1';
Entry(8) = 32;
Entry(9) = 'T';
Entry(10) = 'X';
Entry(11) = 'T';
Entry(12) = 32;
Entry(13) = 0;
Entry(14) = 150;
Entry(15) = 10; Entry(16) = 10;
Entry(17) = 30; Entry(18) = 1;
Entry(19) = 30; Entry(20) = 1;
Entry(21) = 0; Entry(22) = 0;
Entry(23) = 10; Entry(24) = 10;
Entry(25) = 30; Entry(26) = 1;
File_DATA = [65 66 67 68 69 70 71 72 73];
Entry(29) = 9;
Entry(30) = 0;
Entry(31) = 0;
Entry(32) = 0;
File_Size = length(File_DATA);
Entry_Flag = 1; % показує чи ми вже записали номер першого кластеру
for i = 1 : ceil(File_Size / (SecPerClus * BytesPerSec)) %від 1-го до останнього кластеру файлу
%/////////////// Шукаємо вільний кластер в таблиці FAT ////////////////////
Free_ClusNum = 0; %№ вільного кластеру
Flag_Clus = 0;
for ii = 1 : SecPerFAT %всі сектори FAT
Buffer = MMC_SD_Read_Sector(s, FAT_Sect1 + ii - 1);
for jj = 1 : 2 : SecPerFAT * BytesPerSec %всі вказівники в FAT
if (Buffer(jj) + 256 * Buffer(jj + 1) == 0) %якщо кластер вільний
Flag_Clus = 1;
break;
end;
Free_ClusNum = Free_ClusNum + 1;
end;
if (Flag_Clus == 1)
break;
end;
end;
z = sprintf('1-ий вільний кластер: %d', Free_ClusNum);
disp(z);
%Записуємо значення вказівника в таблицю FAT
Buffer(jj) = 255; %останній кластер файлу
Buffer(jj + 1) = 255;
wr = MMC_SD_Write_Sector(s, Buffer, FAT_Sect1 + ii - 1); %!!!!!!!!!!!!!!!!!!!!!!!!!
if (i > 1) %якщо були попередні кластери з даними файлу
Buffer = MMC_SD_Read_Sector(s, FAT_Sect1 + Prev_Sect_FAT - 1);
Buffer(Prev_Index_FAT + 1) = fix(Free_ClusNum/256); %Free_ClusNum той, який зараз
Buffer(Prev_Index_FAT) = Free_ClusNum - 256 * Buffer(Prev_Index_FAT + 1);
wr = MMC_SD_Write_Sector(s, Buffer, FAT_Sect1 + Prev_Sect_FAT - 1); %!!!!!!!!!!!!!!!!!!!!!!!!!
end;
Prev_Sect_FAT = ii; %попередній сектор з номером вільного кластеру в FAT
Prev_Index_FAT = jj; %вказівник на попередній кластер
%///////////////////////// Записуємо файл в область даних /////////////////////
File_Sect = Data_Sect + (Free_ClusNum - 2) * SecPerClus; %сектор початку файлу в DATA Region
Buffer = zeros(BytesPerSec, 1);
if (File_Size <= BytesPerSec)
Buffer(1 : File_Size) = File_DATA;
%wr = MMC_SD_Write_Sector(s, Buffer, File_Sect - 1); %!!!!!!!!!!!!!!!!!!!!!!!!!
wr = MMC_SD_Write_Sector(s, Buffer, File_Sect); %!!!!!!!!!!!!!!!!!!!!!!!!!
else
iii = 1;
for ii = 1 : SecPerClus %ceil(File_Size / BytesPerSec)
Buffer = File_DATA(iii : ii * BytesPerSec);
wr = MMC_SD_Write_Sector(s, Buffer, File_Sect); %!!!!!!!!!!!!!!!!!!!!!!!!!
File_Sect = File_Sect + 1; %наступний сектор
iii = iii + ii * BytesPerSec; %початок наступного сектору (в File_DATA)
end;
end;
if (Entry_Flag == 1)
%Entry( hex2dec('1A') + 1 ) = Free_ClusNum; %записуємо № першого кластеру файлу в запис RootDirectory ???????
Entry(28) = fix(Free_ClusNum/256);
Entry(27) = Free_ClusNum - 256 * Entry(28);
%записуємо створений запис в RootDirectory
Buffer = MMC_SD_Read_Sector(s, Free_Sect_RootDir);
Buffer(32*(Free_Num_RootDir-1) + 1 : 32*(Free_Num_RootDir-1) + 1 +31) = Entry;
wr = MMC_SD_Write_Sector(s, Buffer, Free_Sect_RootDir); %!!!!!!!!!!!!!!!!!!!!!!!!!
end;
Entry_Flag = Entry_Flag + 1;
end;
fclose(s);
Програма запису файлу у wav-форматі:
clear all;
%потрібно задати y – масив даних, які записуємо
%відкрити файл для запису
d = fopen('D:\p\3-ИЙ КУРС\С-ми запису та відтворення інформації\Lab_1\myRecord.wav','wb');
%заповнити поле RIFF_ID (Заголовок RIFF файлу) !!!!!!!!!
fwrite(d,hex2dec('46464952'),'int32');
%заповнити поле FILE_Length (довжина файлу без полів RIFF_ID та FILE_Length)
fwrite(d,110457,'int32');
%заповнити поле WAVE_ID (заголовок блоку інформації) !!!!!!!!!
fwrite(d,hex2dec('45564157'),'int32');
%заповнити поле FMT_ID (ідентифікатор формату) !!!!!!!!!
fwrite(d,hex2dec('20746D66'),'int32');
%заповнити поле FMT_Length (сумарний розмір в байтах полів Type, Channels, SamplesPerSec, AvgBytesPerSec, Align та BitsPerSample)
fwrite(d,16,'int32');
%заповнити поле Type (тип звукових даних (тип кодеку), 0x0001 — просто вибірки)
fwrite(d,1,'int16');
%заповнити поле Channels (число каналів)
fwrite(d,1,'int16');
%заповнити поле SamplesPerSec (частота дискретизації в герцах)
fwrite(d,4000,'int32'); %частота дискретизації така ж як і в Lab_1_10.wav
%заповнити поле AvgBytesPerSec (розмір буферу, обчислюється за формулою (Channels * SamplesPerSec * BitsPerSample) / 8)
fwrite(d,4000,'int32');
%заповнити поле Align (вирівнювання (якщо кількість вибірок не кратна 2, в кінці файлу додається нульове значення). Переважно рівне 0x0001)
fwrite(d,1,'int16');
%заповнити поле BitsPerSample (кількість біт на вибірку)
fwrite(d,8,'int16');
%заповнити поле DATA_ID (заголовок даних) !!!!!!!!!
fwrite(d,hex2dec('61746164'),'int32');
%заповнити поле DATA_Length (кількість вибірок)
fwrite(d,110421,'int32');
%вибірки сигналу
for ii = 1 : 110421
fwrite(d,y(ii)*128 + 128,'uchar');
end;
fclose(d);
Програма стиснення аудіосигналу з потрібною степінню компресії:
clear all;
%Y – нестиснений аудіосигнал
F
B
%wavplay(Y,F,'sync');
Y = Y * 128; % Y -- дробове; треба, щоб було ціле (Y*128)
N = 160; % розмір блоку
L = 34; % к-сть збережених коефіцієнтів ДКП на блок
%***вибираємо так, щоб забезпечити необхідний степінь стиснення***
nn = fix(length(Y)/N); % к-сть блоків
mm = 1;
kk = 1;
% Компресія
for ii = 1 : nn-1
x = dct( Y(kk : kk + N-1) );
y(mm : mm + L-1) = x(1 : L); % В y записуємо лише "великі" відліки
mm = mm + L;
kk = kk + N;
end;
% Квантування
y = round(y); % До цілого
[A, X] = hist(y, min(y) : max(y));
NN = length(y);
Ls = 0;
for ii = 1 : length(A)
if(A(ii) > 0)
Ls = Ls + (A(ii)/NN) * log2(A(ii)/NN);
end;
end;
disp('-Ls = ');
-Ls
CR2 = (10 / -Ls) * (N / L) % CR2 -- cтепінь стиснення
% 10, бо 9 біт на число (тут 3хх), і один на знак (-)
% Відновлений сигнал
YC = Y * 0;
dx = Y(1 : N) * 0;
mm = 1;
kk = 1;
% ...*0 -- це "малі" відліки
for ii = 1 : nn - 1
dx(1 : L) = y(mm : mm + L-1);
x1 = idct( dx );
YC(kk : kk + N-1) = x1;
dx = dx * 0;
mm = mm + L;
kk = kk + N;
end;
YC = YC / 128;
YC = round(YC * 128) / 128;
%wavplay(YC, F, 'sync');
Висновок: В системах захисту широко використовуються прилади призначені для запису та відтворення інформації. Важливою складовою є акустична інформація як така і технічні пристрої призначені для її збору, зберігання та відтворення.
На прикладі цифрового диктофону, я отримав основні навички розробки пристроїв що можуть використовуватись в системах запису і відтворення інформації, засвоїв теоретичний матеріал і використав отримані знання на практиці.
В роботі я склав електричні схеми складових елементів цифрового диктофону, таких як:
Мікрофон і мікрофонний підсилювач;
Фільтр;
Мікроконтролер з вбудованим 10-бітним АЦП;
MMC/SD-карта;
NAND-Flash пам’ять;
Кола живлення;
Органи управління.
Також розробив програмне забезпечення необхідне для роботи пристрою.