Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Laboratornaya_rabota_2.doc
Скачиваний:
7
Добавлен:
16.11.2019
Размер:
1.64 Mб
Скачать

16

Лабораторная работа

Операции над файлами и средства визуализации результатов работы в системе matlab

Цель работы. Изучение приемов работы с массивами и файлами, а также средств визуализации результатов работы.

Справочные сведения из системы MATLAB

Обработка звука и сохранение его в дисковых файлах

Система MATLAB позволяет читать и записывать файлы формата wave. Чтение осуществляется с помощью функции wavread, а запись - с помощью функции wavwrite. Функция sound (а также почти аналогичная ей функция soundsc) осуществляет реальное воспроизведение звука, получая в качестве аргумента вещественный вектор, содержащий последовательность измерений громкости звука.

Пример. Выбрать в одном из системных каталогов Windows стереофонический звуковой файл. Считываем звуковую информацию из этого файла в состоящую из двух столбцов числовую матрицу V

[V,f,b] = wavread ('*.wav');

В скалярную переменную f при этом читается частота дискретизации, в переменную b- разрядность. Читаем переменные b, f , выясняем размер матрицы V, воспроизводим звук с помощью функции sound:

sound( V, f, b )

Величины элементов матрицы отсчетов ограничены диапазоном от -1.0 до +1.0. Встроенных средств по автоматическому преобразованию массива звуковых отсчетов V в ядре системы MATLAB нет, но они имеются в пакете расширения Signal Processing Toolbox, В качестве простейшего примера посмотрим, что получится, если осуществить небольшое "зашумление" звукового сигнала:

[m,n] - size( V );

s = 0.05; V1 = randn( m,n );

V = V + s * V1;

Снова вызываем функцию sound и "слушаем вектор" V, у которого теперь оба столбца содержат сильно зашумленный звук. Коэффициентом ухудшения звука служит переменная s.

Чтобы сохранить результаты любых экспериментов со звуком, нужно записать информацию в файл, для чего следует применить предназначенную для этого функцию wavwrite. В частности, эксперимент с зашумлением сохраним в файле 'MySound1.wav':

wavwrite( V, f, b, 'MySound1.wav' );

Здесь первым аргументом является матрица (для монофоничского звука - это вектор) звуковых отсчетов, вторым - частота дискретизации, третьим - разрядность отсчетов, а последним - имя файла. Если не указывать пути к файлу, то он будет записан в текущий рабочий каталог пакета MATLAB.

Если звуковые отсчеты требуется сохранить в файле другого формата, то для этих целей пакет MATLAB располагает набором специальных функций для работы с файлами произвольных форматов и типов. Под типами понимается разделение файлов на бинарные и текстовые. Звуковые файлы относятся к бинарным файлам.

***Бинарные файлы предназначены для хранения произвольных данных в виде потока байтов. Самые характерные операции с такими файлами - это операции записи или считывания заданного количества байт информации. В противоположность этому содержимое текстовых файлов трактуется как набор всех символов из некоторой кодировки, имеющих визуальное представление, а также заданный набор так называемых управляющих символов, таких как "возврат каретки", "перевод строки", "конец файла". Текстовые файлы служат для хранения текстов, а бинарные файлы больше подходят для плотного (без излишнего расхода памяти) и скрытного (нельзя прочитать их содержимое простейшими текстовыми редакторами типа Notepad) хранения числовых данных и машинных кодов компьютерных программ.

Независимо от типа файла перед началом работы его нужно открыть специальной функцией fopen:

fid = fopen( 'имя_файла', 'флаг' )

где имя файла может предваряться полным путем к нему (иначе файл должен располагаться в текущем каталоге системы MATLAB). Второй параметр этой функции - флаг открытия файла, говорит о способе дальнейшей работы с файлом:

'г' только для чтения

'w' только для записи (предыдущее содержимое теряется, а несуществующий файл создается)

'r+' чтение и запись одновременно

'а' добавление в конец файла

К указанным в текстовых строках буквам следует добавлять букву 'b' для открытия файла в бинарном режиме и букву 't'- для открытия файла в текстовом режиме. Например, флаг 'r+t' означает открытие текстового файла для чтения и записи, флаг 'wb' означает открытие бинарного файла для записи.

Функция fopen возвращает числовой идентификатор открытого файла, который надо использовать в качестве параметра для функций чтения и записи в этот файл. Если операция открытия файла не удалась (это возможно как по причине отсутствия файла, так и по причине неправильного указания пути к нему на диске), то функция fopen возвращает -1. Всегда следует проверять возврат функции fopen.

Если файл больше не требуется, его следует закрыть функцией fclose:

fclose( fid )

Чтение и запись информации в бинарные файлы осуществляются функциями fread и fwrite. Функция fwrite, предназначенная для записи информации в бинарные файлы, имеет следующие аргументы:

fwrite( fid, A, 'precision' ),

где fid - файловый идентификатор, возвращаемый функцией fopen; a -числовой вектор или матрица, чьи элементы подлежат записи в файл; строка 'precision' говорит о размере памяти, отводимой под вещественные числа. В системе MATLAB под вещественные числа отводят 8 байт или 64 бита. Указанием функции fwrite о таком размере памяти служит текстовая строка 'float64'.

Пример. В следующем фрагменте создаются вектор-столбец а размером 3x1 и матрица в размером 2x3, которые затем записываются в файл с именем 'dataTest.gqw' (столь вычурное расширение имени файла выбрано специально, чтобы оно случайно не совпало с расширениями файлов известных Windows-приложений):

а=[1;2;3];В=[456;789]; fid1 = fopen('dataTest.gqw', 'wb' );

fwrite( fidl, a, 'float64' );

fwrite( fidl, В, 'float64' ); fclose( fidl );

Чтобы прочитать записанный файл, нужно воспользоваться предназначенной для этого функцией fread. Вот наиболее полный формат вызова этой функции:

[A,count] = fread( fid, size, 'precision' )

Здесь строка 'precision' имеет тот же самый смысл, что и рассмотренный выше для функции fwrite. Параметр size при чтении информации из файла задает как количество подлежащих прочтению числовых элементов с размером, определяемым третьим аргументом, так и организацию этих элементов в выходном числовом массиве а (например, количество строк и столбцов).

Теперь можно прочитать из файла сохраненные там значения вектора а и матрицы B, что и иллюстрирует следующий фрагмент кода:

fidl = fopen( 'dataTest.gqw', 'rb' );

[ a , count ] = fread( fidl, [3,1], 'float64' );

[ В , count ] = fread( fidl, [2,3], 'float64' );

fclose( fidl );

Убедитесь, что прочитанные значения совпадают с ранее записанными. Это произошло потому, что мы точно знаем, что и в каком порядке было записано в файл (ранее мы изучили, что в памяти компьютера массивы хранятся по столбцам, но они точно в таком же порядке записываются в файлы и читаются из них). Именно это имеют в виду, когда говорят о знании формата файла. Если формат бинарного файла неизвестен, то правильно интерпретировать его содержимое невозможно.

Второе возвращаемое значение, count, равно числу реально прочитанных вещественных чисел. При чтении вектора а это число будет равно 3, а при чтении матрицы B - будет равно 6.

B =

456

789

count = 6

Чтобы сразу после открытия сформированного выше бинарного файла 'dataTest.gqw' прочитать элементы матрицы в размером 2x3, не читая предварительно вектор а размером, нужно воспользоваться функцией fseek для позиционирования файлового указателя.

После открытия файла его указатель расположен перед самым первым байтом, так что он показывает на тот байт, который будет прочитан первой же операцией чтения из этого файла. После прочтения одного вещественного числа файловый указатель продвинется на восемь байт вперед и расположится перед девятым байтом. Таким образом, по мере чтения чисел из файла его указатель продвигается вперед и всегда располагается перед первым еще не прочитанным байтом. Текущее положение файлового указателя можно узнать, вызвав функцию ftell:

CurPos = ftell( fid );

Для изменения текущего положения файлового указателя и служит функция fseek:

fseek( fid, number, 'flag' ),

перемещающая этот указатель на number байт (вперед или назад в зависимости от знака целого числа number) от его текущего положения, если 'flag' представлен строкой 'cof', или от начала файла - когда параметр 'flag' есть 'bof', и, наконец, в случае значения флага 'eof' перемещение файлового указателя отсчитывается от конца файла.

В результате следующий фрагмент позволяет прочитать из файла 'dataTest.ggw' только матричную составляющую этого файла:

fidl = fopen( 'dataTest.gqw', 'rb' );

fseek( fidl, 24, 'bof' );

[ В , count ] = fread( fidl, [2,3], 'float64' );

fclose( fidl );

поскольку мы с помощью функции fseek пропускаем от начала файла первые 24=3*8 байт (три вещественных числа в формате пакета MATLAB).

Возможна ошибочная ситуация, когда осуществляется попытка чтения файла после того, как все его содержимое уже прочитано, и файловый указатель расположен вслед за последним байтом файла. Эту ситуацию можно выявить с помощью функции feof, принимающей в качестве своего единственного аргумента файловый идентификатор. Если конец файла уже достигнут, то функция возвращает логическую единицу ("истину", то есть просто 1), а в противном случае эта функция возвратит нуль ("ложь").

Если не осуществлять проверку на достижение конца файла и продолжать читать файл, то получается следующий результат:

fread(fidl,8,'fIoat64') ans =Empty matrix: 8-by-O

говорящий о том, что результатом чтения файла может быть лишь пустой (не содержащий элементов) массив. Если все же возникают какие-то сомнения, то тогда следует вызвать функцию ferror, говорящую о том же самом, но уже открытым текстом (см. рис. 1).

Рис. 1

Для повторного прочтения файла можно вызвать функцию frewind( fid )

возвращающую файловый указатель на начало файла.***

Пример. Сначала прочтем звуковой файл

[V,f,b] = wavread('windoweLogonSound.wav');

специализированной "звуковой" функцией wavread, после чего сохраним все полезные данные, то есть матрицу V и скаляры f и b с помощью файловых функций общего назначения:

fidl = fopen( 'MySound.sound', 'wb' );

fwrite( fidl, V, 'float64' );

fwrite( fidl, f, 'float64' );

fwrite( fidl, b, 'float64' )-;

fclose( fidl );

Такой файл нужно читать с помощью функций чтения общего назначения, опираясь на наше знание формата этого файла:

fidl = fopen( 'MySound.Bound', 'rb' );

[V,count]=fread(fidl,[121536,2],'float64');

[f,count]=fread(fidl,[1,1],'float64');

[b,count]=fread(fidl,[1,1],'float64');

fclose(fidl);

после чего полученные данные в виде v, f и b можно подавать на вход функции sound для прослушивания.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]