メインコンテンツ

read

次の連続信号観測値の読み取り

説明

sig = read(sds) は、データストアから抽出した信号データを返します。read への後続の呼び出しごとに、データストアの次のファイル (sds がファイル データを含む場合) または次のメンバー (sds がインメモリ データを含む場合) からデータが返されます。

[sig,info] = read(sds) は、抽出した信号データに関する情報も返します。

すべて折りたたむ

MATLAB® に MAT ファイルとして含まれているオーディオ信号セットへのパスを指定します。

folder = fullfile(matlabroot,"toolbox","matlab","audiovideo");

指定したフォルダーを示す信号データストアを作成し、サンプル レート変数の名前を Fs に設定します。データストア内の MAT ファイルの名前をリストします。

sds = signalDatastore(folder, ...
    FileExtension=".mat",SampleRateVariableName="Fs");
[~,c] = fileparts(sds.Files)
c = 7×1 cell
    {'chirp'   }
    {'gong'    }
    {'handel'  }
    {'laughter'}
    {'mtlb'    }
    {'splat'   }
    {'train'   }

信号データストアに読み取られていないファイルがある場合、連続したファイルをデータストアから読み取ります。関数 progress を使用して、読み取られたファイルの割合を監視します。

while hasdata(sds)
    [data,info] = read(sds);
    fprintf("Fraction of files read: %.2f\n",progress(sds))
end
Fraction of files read: 0.14
Fraction of files read: 0.29
Fraction of files read: 0.43
Fraction of files read: 0.57
Fraction of files read: 0.71
Fraction of files read: 0.86
Fraction of files read: 1.00

関数 read への最後の呼び出しで返された info 構造体を出力して精査します。

info
info = struct with fields:
             SampleRate: 8192
       TimeVariableName: "Fs"
    SignalVariableNames: "y"
               FileName: "/mathworks/devel/bat/filer/batfs2566-0/Bdoc25b.2988451/build/runnable/matlab/toolbox/matlab/audiovideo/train.mat"

信号データストアを作成して、信号データのインメモリ cell 配列の要素を反復します。データは正弦波変調された線形チャープ、凹二次チャープ、および電圧制御発振器で構成されます。信号は、3000 Hz でサンプリングされます。

fs = 3000;
t = 0:1/fs:3-1/fs;
data = {chirp(t,300,t(end),800).*exp(2j*pi*10*cos(2*pi*2*t)); ...
        2*chirp(t,200,t(end),1000,'quadratic',[],'concave'); ...
        vco(sin(2*pi*t),[0.1 0.4]*fs,fs)};
sds = signalDatastore(data,'SampleRate',fs);

データストアにデータがある場合は、信号データストアから各観測値を読み取り、短時間フーリエ変換をプロットします。

plotID = 1;
while hasdata(sds)
    [dataOut,info] = read(sds);
    subplot(3,1,plotID)
    stft(dataOut,info.SampleRate)
    plotID = plotID + 1;
end

Figure contains 3 axes objects. Axes object 1 with title Short-Time Fourier Transform, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image. Axes object 2 with title Short-Time Fourier Transform, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image. Axes object 3 with title Short-Time Fourier Transform, xlabel Time (s), ylabel Frequency (kHz) contains an object of type image.

MATLAB® に含まれる 4 つの信号へのパスを指定します。これらの信号は、鳥の鳴き声、銅鑼、汽車、およびスプラット (ペチャッという音) の録音です。すべての信号は、8192 Hz でサンプリングされます。

folder = fullfile(matlabroot,'toolbox','matlab','audiovideo', ...
         ["chirp.mat","gong.mat","train.mat","splat.mat"]);

指定したファイルを示す信号データストアを作成します。各ファイルには、サンプル レートを示す変数 Fs が含まれています。

sds1 = signalDatastore(folder,'SampleRateVariableName','Fs');

関数 read の出力を取得し、少なくとも 80 サンプル単位に分割された局地的最大値に対してスプライン内挿を使用して信号の上側包絡線と下側包絡線を計算する関数を定義します。この関数はさらに、各信号のサンプル時間を返します。

function [dataOut,infoOut] = signalEnvelope(dataIn,info)
    [dataOut(:,1),dataOut(:,2)] = envelope(dataIn,80,'peak');
    infoOut = info;
    infoOut.TimeInstants = (0:length(dataOut)-1)/info.SampleRate;
end

関数 transform を呼び出して、2 番目のデータストア sds2 を作成します。このデータストアでは、定義した関数を使用して信号の包絡線を計算します。

sds2 = transform(sds1,@signalEnvelope,"IncludeInfo",true);

sds1sds2 を結合して 3 番目のデータストアを作成します。結合したデータストアに対して関数 read を呼び出すたびに、次の 3 列をもつ行列が返されます。

  • 1 列目は元の信号に対応します。

  • 2 列目と 3 列目は、それぞれ上側包絡線と下側包絡線に対応します。

sdsCombined = combine(sds1,sds2);

結合したデータストアから、元のデータと上側包絡線および下側包絡線を読み取って表示します。関数extractBetweenを使用して、ファイル パスからファイル名を抽出します。

tiledlayout('flow')
while hasdata(sdsCombined)
    [dataOut,infoOut] = read(sdsCombined);
    ts = infoOut{2}.TimeInstants;
    nexttile
    hold on
    plot(ts,dataOut(:,1),'Color','#DCDCDC','LineStyle',':')
    plot(ts,dataOut(:,2:3),'Linewidth',1.5)
    hold off
    xlabel('Time (s)')
    ylabel('Signal')
    title(extractBetween(infoOut{:,2}.FileName,'audiovideo\','.mat'))
end

Figure contains 4 axes objects. Axes object 1 with xlabel Time (s), ylabel Signal contains 3 objects of type line. Axes object 2 with xlabel Time (s), ylabel Signal contains 3 objects of type line. Axes object 3 with xlabel Time (s), ylabel Signal contains 3 objects of type line. Axes object 4 with xlabel Time (s), ylabel Signal contains 3 objects of type line.

sample_chirps フォルダーには、Signal Processing Toolbox™ に含まれるサンプル ファイルが格納されています。各ファイルには、チャープと 100 ~ 150 Hz の範囲のランダム サンプル レート fs が含まれます。sample_chirps 内の 4 つのファイルを指す信号データストアを作成し、サンプル レート変数の名前を指定します。

addpath("sample_chirps")
files = ["chirp_1.mat","chirp_4.mat","chirp_9.mat","chirp_10.mat"];
sds = signalDatastore(files,SampleRateVariableName="fs");

関数 read の出力を取得し以下を計算して返す関数を定義します。

  • チャープのスペクトログラム。

  • ウィンドウ セグメントの中心に対応する時点のベクトル。

  • 推定値に対応する周波数。

function [dataOut,infoOut] = extractSpectrogram(dataIn,info)
    [dataOut,F,T] = pspectrum(dataIn,info.SampleRate,"spectrogram",...
                              TimeResolution=0.25,...
                              OverlapPercent=40,Leakage=0.8);
    infoOut = info;
    infoOut.CenterFrequencies = F;
    infoOut.TimeInstants = T;
end

関数 transform を呼び出し、定義した関数を使用して各チャープのスペクトログラムを計算するデータストアを作成します。

sdsNew = transform(sds,@extractSpectrogram,IncludeInfo=true);

変換したデータストアに読み取られていないファイルがある場合、新しいデータストアから読み取って、3 次元空間でスペクトログラムを可視化します。

t = tiledlayout("flow");
while hasdata(sdsNew)
    nexttile
    [sig,infoOut] = read(sdsNew);
    waterfall(infoOut.TimeInstants,infoOut.CenterFrequencies,sig)
    xlabel("Frequency (Hz)")
    ylabel("Time (S)")
    view([30 70])
end

Figure contains 4 axes objects. Axes object 1 with xlabel Frequency (Hz), ylabel Time (S) contains an object of type patch. Axes object 2 with xlabel Frequency (Hz), ylabel Time (S) contains an object of type patch. Axes object 3 with xlabel Frequency (Hz), ylabel Time (S) contains an object of type patch. Axes object 4 with xlabel Frequency (Hz), ylabel Time (S) contains an object of type patch.

MATLAB® に含まれる信号の例へのファイル パスを指定します。指定したフォルダーを示す信号データストアを作成します。

folder = fullfile(matlabroot,'toolbox','matlab','audiovideo');
sds = signalDatastore(folder,'SampleRateVariableName','Fs');

信号データストアの区画の既定の数を取得します。

n = numpartitions(sds)
n = 
7

データストアを既定の数の区画に分割し、4 番目の区画に対応するデータストアを返します。

subsds = partition(sds,n,4);

関数extractAfterを使用して、4 番目の区画に対応するデータストアに含まれるファイルの名前を表示します。

fName = extractAfter(subsds.Files,'audiovideo\')
fName = 1×1 cell array
    {0×0 char}

4 番目の区画に対応するデータストアの信号に関するデータと情報を読み取ります。info からサンプル レートを抽出し、信号を元のサンプル レートの半分にリサンプリングします。元の信号とリサンプリングした信号をプロットします。

while hasdata(subsds)
    [data,info] = read(subsds);
    fs = info.SampleRate;
    f_res = 0.5*fs;
    ts = (0:length(data)-1)/fs;
    data_res = resample(data,1,2);
    t_res = (0:length(data_res)-1)/f_res;
    plot(ts,data,t_res,data_res,':')
    xlabel('Time (s)')
    ylabel('Signal')
    legend('Original','Resampled','Location','NorthWest')
end

Figure contains an axes object. The axes object with xlabel Time (s), ylabel Signal contains 2 objects of type line. These objects represent Original, Resampled.

入力引数

すべて折りたたむ

信号データストア。signalDatastore オブジェクトとして指定します。

出力引数

すべて折りたたむ

信号データ。配列として返されます。既定では、read を 1 回呼び出すと、1 回につき 1 つのファイルの最初の変数が返されます。ReadSize プロパティを n に設定した場合 (n > 1)、関数 read が呼び出されるたびに関数は以下を読み取ります。

  • sds にファイル データが含まれている場合における、最初の n ファイルの最初の変数

  • sds にインメモリ データが含まれている場合における、最初の n メンバー

メモ

ファイルの最初の変数名を決めるために、read は以下の手順に従います。

  • MAT ファイルの場合:

    s = load(fileName);
    varNames = fieldnames(s);
    firstVar = s.(varNames{1});

  • CSV ファイルの場合:

    opts = detectImportOptions(fileName,'PreserveVariableNames',true);
    varNames = opts.VariableNames;
    firstVar = string(varNames{1});

データストアの SignalVariableNames プロパティに複数の信号名が含まれている場合、sig は cell 配列です。データストアの ReadOutputOrientation プロパティを使用して、sig の向きを列配列または行配列として制御します。

信号データに関する情報。構造体として返されます。

  • ファイル データの場合、info には、signalDatastore で指定されていれば、時間情報 (指定されている場合)、ファイル名、および信号と時間データの読み取りに使用される変数名が含まれます。

  • インメモリ データがデータストアに含まれる場合、info には、時間情報 (指定されている場合) およびメンバー名が含まれます。

バージョン履歴

R2020a で導入