DTLN example: (#2012)

Adding DTLN example to demonstrates LSTM layers on HiFi DSP and NOT for evaluating noise suppression quality.

BUG=none
diff --git a/tensorflow/lite/micro/examples/dtln/Makefile.inc b/tensorflow/lite/micro/examples/dtln/Makefile.inc
new file mode 100644
index 0000000..a64686e
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/Makefile.inc
@@ -0,0 +1,27 @@
+
+DTLN_TEST_SRCS := \
+$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_test.cc \
+$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
+
+DTLN_TEST_HDRS := \
+$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
+
+DTLN_GENERATOR_INPUTS := \
+$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite
+
+DTLN_GENERATED_SRCS := \
+$(GENERATED_SRCS_DIR)$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.cc
+
+DTLN_GENERATED_HDRS := \
+$(GENERATED_SRCS_DIR)$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.h
+
+#Find any platform - specific rules for this example.
+include $(wildcard $(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/*/Makefile.inc)
+
+# TODO(b/161489252): Disabling warnings for this example until we have a better
+# way to build third_party code with a reduced list of CFLAGS.
+CCFLAGS := $(filter-out $(CC_WARNINGS),$(CCFLAGS))
+
+# Tests loading and running a dtln model.
+$(eval $(call microlite_test,dtln_test,\
+$(DTLN_TEST_SRCS),$(DTLN_TEST_HDRS),$(DTLN_GENERATOR_INPUTS)))
diff --git a/tensorflow/lite/micro/examples/dtln/README.md b/tensorflow/lite/micro/examples/dtln/README.md
new file mode 100644
index 0000000..eb96b0c
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/README.md
@@ -0,0 +1,23 @@
+# DTLN example
+The DTLN example is a demonstration of DTLN network running on HiFi DSP for Noise suppression in speech.
+It uses feature_data as input and provides noise suppressed speech as output.
+It is based on the paper(https://github.com/breizhn/DTLN).
+While paper presents 2 parts, one for noise suppression and the other for speech enhancement, 
+the example presented here follows the noise suppression part only.
+The model was re-trained by Cadence using the DNS challenge data (https://github.com/microsoft/DNS-Challenge) 
+and the noise suppression part was 8-bit quantized. 
+This example is not to be used to evaluate the network quality or quality of noise suppression, but only as a demonstration as stated above.
+
+## Run the tests on a development machine
+
+```
+make -f tensorflow/lite/micro/tools/make/Makefile third_party_downloads
+make -f tensorflow/lite/micro/tools/make/Makefile test_dtln_test
+```
+
+You should see a series of files get compiled, followed by some logging output
+from a test, which should conclude with `~~~ALL TESTS PASSED~~~`. If you see
+this, it means that a small program has been built and run that loads a trained
+TensorFlow model, runs with features data, and got the expected
+outputs. This particular test runs with a feature data as input,
+and validate the output with golden reference output.
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
new file mode 100644
index 0000000..a4652a7
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
@@ -0,0 +1,60 @@
+/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "tensorflow/lite/c/common.h"
+
+int8_t feature_data[] = {
+    -127, -126, -115, -82,  -90,  -113, -15,  13,   -87,  -105, -77,  -106,
+    -113, -81,  -90,  -123, -113, -112, -124, -120, -114, -123, -123, -112,
+    -115, -125, -120, -120, -126, -126, -126, -127, -128, -127, -128, -128,
+    -127, -127, -128, -126, -125, -126, -127, -127, -127, -128, -126, -127,
+    -128, -127, -127, -128, -127, -126, -127, -128, -127, -127, -127, -124,
+    -124, -127, -126, -126, -127, -126, -124, -125, -128, -126, -125, -127,
+    -126, -126, -127, -127, -126, -126, -127, -126, -126, -127, -126, -125,
+    -127, -126, -123, -124, -126, -126, -126, -128, -127, -127, -127, -128,
+    -127, -127, -128, -128, -128, -128, -128, -127, -128, -128, -127, -128,
+    -128, -127, -127, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -127, -127, -127, -127, -127,
+    -127, -127, -127, -128, -127, -127, -127, -127, -126, -127, -127, -127,
+    -127, -127, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+    -128, -127, -128, -128, -127, -127, -128, -128, -128, -128, -128, -128,
+    -128, -128, -128, -128, -128};
+
+int8_t golden_ref[] = {
+    119, 82,  72,  116, -5,  10,  -2,  0,   -2,  36,  116, 125, 123, 124, 126,
+    124, 115, 116, 124, 126, 121, 124, 121, 104, 104, 113, 113, 110, 115, 101,
+    96,  119, 120, 117, 118, 114, 104, 110, 118, 119, 111, 114, 119, 117, 114,
+    110, 117, 112, 115, 120, 119, 118, 119, 116, 117, 120, 121, 121, 121, 119,
+    117, 120, 121, 120, 118, 115, 114, 114, 117, 119, 113, 108, 108, 111, 112,
+    114, 114, 116, 115, 112, 110, 113, 113, 110, 107, 98,  102, 101, 101, 103,
+    92,  98,  101, 102, 102, 101, 104, 102, 101, 101, 100, 102, 98,  104, 100,
+    99,  92,  96,  87,  97,  96,  96,  96,  95,  92,  98,  95,  90,  85,  82,
+    87,  82,  82,  89,  90,  83,  86,  85,  80,  86,  87,  91,  89,  87,  87,
+    85,  82,  74,  80,  80,  72,  79,  74,  79,  82,  83,  77,  85,  71,  76,
+    72,  76,  76,  77,  56,  74,  74,  69,  69,  69,  65,  56,  60,  67,  71,
+    69,  74,  67,  71,  65,  77,  76,  79,  67,  72,  61,  60,  67,  69,  71,
+    77,  63,  63,  60,  63,  71,  80,  80,  74,  76,  67,  74,  63,  67,  69,
+    72,  77,  71,  72,  82,  65,  49,  67,  58,  71,  65,  63,  69,  61,  77,
+    63,  65,  65,  69,  69,  65,  72,  77,  80,  60,  79,  77,  71,  67,  79,
+    69,  67,  65,  74,  69,  71,  67,  76,  77,  77,  77,  83,  67,  65,  79,
+    77,  60,  71,  86,  86,  63,  74,  63,  63,  63,  69,  79,  63,  52,  85,
+    87,  86};
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
new file mode 100644
index 0000000..c5fde46
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
@@ -0,0 +1,19 @@
+/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "tensorflow/lite/c/common.h"
+
+extern int8_t feature_data[];
+extern int8_t golden_ref[];
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite b/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite
new file mode 100644
index 0000000..143ef8d
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite
Binary files differ
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_test.cc b/tensorflow/lite/micro/examples/dtln/dtln_test.cc
new file mode 100644
index 0000000..1077195
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_test.cc
@@ -0,0 +1,100 @@
+/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "tensorflow/lite/c/common.h"
+#include "tensorflow/lite/micro/examples/dtln/dtln_inout_data.h"
+#include "tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.h"
+#include "tensorflow/lite/micro/micro_interpreter.h"
+#include "tensorflow/lite/micro/micro_log.h"
+#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
+#include "tensorflow/lite/micro/testing/micro_test.h"
+#include "tensorflow/lite/schema/schema_generated.h"
+
+TF_LITE_MICRO_TESTS_BEGIN
+
+MicroPrintf(
+    "\nThis example demonstrates LSTM layers on HiFi DSP, NOT for evaluating "
+    "noise suppression quality.\n");
+TF_LITE_MICRO_TEST(TestInvoke) {
+  // Map the model into a usable data structure. This doesn't involve any
+  // copying or parsing, it's a very lightweight operation.
+  const tflite::Model* model =
+      ::tflite::GetModel(g_dtln_noise_suppression_model_data);
+  if (model->version() != TFLITE_SCHEMA_VERSION) {
+    MicroPrintf(
+        "Model provided is schema version %d not equal "
+        "to supported version %d.\n",
+        model->version(), TFLITE_SCHEMA_VERSION);
+  }
+
+  // Pull in only the operation implementations we need.
+  // This relies on a complete list of all the ops needed by this graph.
+
+  tflite::MicroMutableOpResolver<3> micro_op_resolver;
+  micro_op_resolver.AddUnidirectionalSequenceLSTM();
+  micro_op_resolver.AddFullyConnected();
+  micro_op_resolver.AddLogistic();
+
+  // Create an area of memory to use for input, output, and intermediate arrays.
+  constexpr int tensor_arena_size = 16 * 1024;
+  alignas(16) uint8_t tensor_arena[tensor_arena_size];
+
+  // Build an interpreter to run the model with.
+  tflite::MicroInterpreter interpreter(model, micro_op_resolver, tensor_arena,
+                                       tensor_arena_size);
+  interpreter.AllocateTensors();
+
+  // Get information about the memory area to use for the model's input.
+  TfLiteTensor* input = interpreter.input(0);
+
+  // Make sure the input has the properties we expect.
+  TF_LITE_MICRO_EXPECT(input != nullptr);
+  TF_LITE_MICRO_EXPECT_EQ(3, input->dims->size);
+  TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]);
+  TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[1]);
+  TF_LITE_MICRO_EXPECT_EQ(257, input->dims->data[2]);
+  TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, input->type);
+
+  // Copy a spectrogram created from a noisy.wav audio file,
+  // into the memory area used for the input.
+  for (size_t i = 0; i < input->bytes; ++i) {
+    input->data.int8[i] = feature_data[i];
+  }
+
+  // Run the model on this input and make sure it succeeds.
+  TfLiteStatus invoke_status = interpreter.Invoke();
+  if (invoke_status != kTfLiteOk) {
+    MicroPrintf("Invoke failed\n");
+  }
+  TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status);
+
+  // Get the output from the model, and make sure it's the expected size and
+  // type.
+  TfLiteTensor* output = interpreter.output(0);
+  TF_LITE_MICRO_EXPECT_EQ(3, output->dims->size);
+  TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]);
+  TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[1]);
+  TF_LITE_MICRO_EXPECT_EQ(257, output->dims->data[2]);
+  TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type);
+
+  int output_size =
+      output->dims->data[0] * output->dims->data[1] * output->dims->data[2];
+  for (int i = 0; i < output_size; i++)
+    TF_LITE_MICRO_EXPECT_EQ(output->data.int8[i], golden_ref[i]);
+
+  MicroPrintf("Ran successfully\n");
+}
+
+TF_LITE_MICRO_TESTS_END