#はじめに
何らかの処理をすべきファイルが大量にあって,一つ一つ手作業で処理をするのは大変である.
指定したフォルダ内の指定した拡張子のファイルを一括で処理したい.
今回はサンプルとして,
指定したフォルダとそのサブフォルダ内の全てのWAVファイルを検索し,一つ一つのファイルを開いて,時間波形を描いてPNGで保存する
という処理をMATLABで作っていく.
その他細かい話として,
PNGの保存先は元のWAVと同じとし,ファイル名は「元のWAVファイル名.png」とする
処理中はプロセスバーを表示する
とする.
#ファイルを検索する
rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
if(rootDir==0)
disp('処理を終了します');
return
end
% カレントディレクトリをバッファ
origDir = pwd;
% カレントディレクトリを変更
cd(rootDir);
% カレントディレクトリとサブディレクトリを検索
fileList = dir('**/*.WAV');
% カレントディレクトリを戻す
cd(origDir);
##フォルダ選択ダイアログ
rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
でフォルダ選択ダイアログが出てきて,rootDir
に指定したフォルダのフルパスが入る.
なお,ダイアログをキャンセルで閉じた場合はrootDir
には0
が入る.
##ファイルリストの取得
fileList = dir('**/*.WAV'); % で指定したフォルダとサブフォルダを検索
% もしくは
fileList = dir('*.WAV'); % と打つと指定したフォルダだけを検索する
fileList
は以下のようなフィールドなどが入っている構造体である.
フィールド名 | 説明 |
---|---|
name | ファイル名またはフォルダ名 |
folder | ファイルまたはフォルダのフルパス |
構造体の詳細は フォルダーの内容の一覧表示 -MATLAB dir- MathWorks を参照.
#ファイルを一つ一つ処理する
% 1つ1つファイルを処理していく
for n = 1:length(fileList)
% ファイルのフルパスを取得
fullpath = fullfile(fileList(n).folder, fileList(n).name);
% メインの処理
sampleSaveGraph(fullpath);
end
##ファイルのフルパスの取得
fullpath = fullfile('C:\aaa\bbb', 'ccc.txt')
と打つと,fullpath
に'C:\aaa\bbb\ccc.txt'
が入る.
fullpath = ['C:\aaa\bbb' '\' 'ccc.txt'];
でもいいと思うけど,Linuxだとファイル区切り文字が'/'
になるので,fullfile
を使ったほうがマルチプラットフォームに対応していて捗るらしい.
##メインの処理
sampleSaveGraph
は自作の関数で,引数にWAVファイルのフルパスを入れると時間波形を作成してグラフを保存してくれる.
実装は↓みたいな感じ.
function sampleSaveGraph(fullpath)
% WAVを開く
[y, Fs] = audioread(fullpath);
% グラフを描く
N = length(y);
t = ((1:N)-1)/Fs;
h = figure('WindowState','minimized');
plot(t, y);
xlim([0, t(end)]);
ylim([-1, 1]);
[filepath ,name, ext] = fileparts(fullpath);
% グラフタイトルはWAVファイル名とする
title([name, ext],'Interpreter','none');
xlabel('時間[秒]');
ylabel('振幅');
% 保存するファイルのフルパスを生成
filename = fullfile(filepath,[name, '.png']);
% ファイルを保存
saveas(h, filename);
close(h);
end
###Figureを最小化状態で立ち上げ
h = figure('WindowState','minimized');
とすると,最小化した状態のFigureウィンドウを立ち上げてくれるらしい.
そのまま立ち上げちゃうとプロセスバーが隠れて見えなくなっちゃうので,最小化で処置をした.
###ファイル名をグラフのタイトルにつける
[filepath ,name, ext] = fileparts(fullpath);
title([name, ext],'Interpreter','none');
でファイル名をタイトル表示する.
titleにInterpreterオプションをつけないと,ファイル名にアンダースコアがあった場合に下付き文字と判定されて上記画像のように表示されるので注意.
#プロセスバーを表示
% プロセスバーを立ち上げる
h = waitbar(0, waitBarText(0, length(fileList)));
% 1つ1つファイルを処理していく
for n = 1:length(fileList)
% メインの処理
% プロセスバーを更新
waitbar(n/length(fileList), h, waitBarText(n, length(fileList)));
end
% プロセスバーを閉じる
close(h);
function s = waitBarText(n, total)
s = sprintf('Please wait...[%d/%d]', n, total);
end
waitbar
の第一引数には0~1の実数が入る.
上記のようなプロセスバーが出てくる.
#処理全体
clc
clear all
close all
rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
if(rootDir==0)
disp('処理を終了します');
return
end
% カレントディレクトリをバッファ
origDir = pwd;
% カレントディレクトリを変更
cd(rootDir);
% カレントディレクトリとサブディレクトリを検索
fileList = dir('**/*.WAV');
% カレントディレクトリを戻す
cd(origDir);
% プロセスバーを表示
h = waitbar(0, waitBarText(0, length(fileList)));
% 1つ1つファイルを処理していく
for n = 1:length(fileList)
% ファイルのフルパスを取得
fullpath = fullfile(fileList(n).folder, fileList(n).name);
% メインの処理
sampleSaveGraph(fullpath);
% プロセスバーを更新
waitbar(n/length(fileList), h, waitBarText(n, length(fileList)));
end
close(h);
disp('処理が完了しました.');
function s = waitBarText(n, total)
s = sprintf('Please wait...[%d/%d]', n, total);
end
##実行結果
###実行前
試しにWAVファイルを4個用意した.(内1個は新しいフォルダー内に保存)
###実行後
期待通りに,画像が保存された.