%% Label Spoken Words in Audio Signals Using External API
% This example shows how to label spoken words in Signal Labeler. The example uses the IBM® Watson Speech to Text API and Audio Toolbox™ software. See Speech-to-Text Transcription for instructions about:
% Downloading the Audio Toolbox speech2text extended functionality, available from MATLAB® Central.
% Setting up the IBM Watson Speech API, offered through IBM Cloud Services. You must create an IBM Cloud account, a Speech to Text service instance, and go to the service dashboard and copy your credentials – API Key and URL values. See the Getting Started Tutorial in the IBM documentation for more details.
%% Load Speech Data
% Load an audio data file containing the sentence "Oak is strong, and also gives shade" spoken by a male voice. The signal is sampled at 44.1 kHz.

[y,fs] = audioread('oak.m4a');

% To hear, type soundsc(y,fs)

% Open Signal Labeler. On the Labeler tab, click Import ▼ and select From workspace in the Members list. In the dialog box, select the signal, y.
% Add time information: Select Time from the drop-down list and specify fs as the sample rate, which is measured in kHz.
% Close the dialog box. The signal appears in the Labeled Signal Set Browser.
%
%% Define Label
% Define a label to attach to the signal. Click Add Definition ▼ on the Labeler tab. Specify the Label Name as Words, select a Label Type of ROI, and enter the Data Type as string.
%
%% Create Custom Autolabeling Function
% Create a custom function to label the words spoken in the audio file. (Code for the stt function appears later in the example.) See Custom Labeling Functions for more information.
% Go to the directory where you have stored the speech2text P-code files and the JSON file that stores your IBM Cloud credentials.
% To create the function, in the Labeler tab, click Automate Value ▼ and select Add Custom Function. Signal Labeler shows a dialog box asking you to enter the name, description, and label type of the function you are adding. Enter stt in the Name field and select ROI as the Label Type. You can leave the Description field empty or you can enter your own description.
% Copy the function code and paste it in the empty template that appears. Save the file. The function appears in the gallery.
%
%
%% Locate and Identify Spoken Words
% Locate and identify the words spoken in the input signal.
% In the Labeled Signal Set Browser, select the check box next to y.
% Select Words in the Label Definitions browser.
% On the Automated Value gallery, select stt.
% Click Auto-Label ▼ and select Auto-Label Signals. Click OK in the dialog box that appears.
% Signal Labeler locates and labels the spoken words.
%
%
%% Export Labeled Signal
% Export the labeled signal. On the Labeler tab, click Export ▼ and select Labeled Signal Set To File. In the dialog box that appears, give the name Transcription.mat to the labeled signal set and add an optional short description. Click Export.
% Go back to the MATLAB® Command Window. Load the labeled signal set. The set has only one member. Get the names of the labels, and use the name to obtain and display the transcribed words.

load Transcription

ln = getLabelNames(transcribedAudio);

v = getLabelValues(transcribedAudio,1,ln)

% Change the label values from strings to categories. Use a signalMask object to plot the signal using a different color for each word.

v.Value = categorical(v.Value,v.Value);

msk = signalMask(v,'SampleRate',fs);

s = getSignal(transcribedAudio,1);

plotsigroi(msk,s.y)

%
%% stt Function: Locate and Identify Spoken Words
% This function uses the IBM Watson Speech API and the Audio Toolbox speech2text extended functionality to extract spoken words from an audio file.

function [labelVals,labelLocs] = stt(x,t,parentLabelVal,parentLabelLoc,varargin)

aspeechObjectIBM = speechClient('IBM','timestamps',true);

fs = 1/(t(2)-t(1));

tixt = speech2text(aspeechObjectIBM,x,fs);

numLabels = numel(tixt.TimeStamps{:});
labelVals = strings(numLabels,1);
labelLocs = zeros(numLabels,2);

for idx = 1:numLabels
    labelVals(idx) = tixt.TimeStamps{:}{idx}{1};
    labelLocs(idx,1) = tixt.TimeStamps{:}{idx}{2};
    labelLocs(idx,2) = tixt.TimeStamps{:}{idx}{3};
end

end

% Copyright 2019 The MathWorks, Inc.