1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/audio_processing/transient/transient_detector.h"
12
13#include <sstream>
14#include <string>
15
16#include "testing/gtest/include/gtest/gtest.h"
17#include "webrtc/base/scoped_ptr.h"
18#include "webrtc/modules/audio_processing/transient/common.h"
19#include "webrtc/modules/audio_processing/transient/file_utils.h"
20#include "webrtc/system_wrappers/include/file_wrapper.h"
21#include "webrtc/test/testsupport/fileutils.h"
22#include "webrtc/typedefs.h"
23
24namespace webrtc {
25
26static const int kSampleRatesHz[] = {ts::kSampleRate8kHz,
27                                     ts::kSampleRate16kHz,
28                                     ts::kSampleRate32kHz,
29                                     ts::kSampleRate48kHz};
30static const size_t kNumberOfSampleRates =
31    sizeof(kSampleRatesHz) / sizeof(*kSampleRatesHz);
32
33// This test is for the correctness of the transient detector.
34// Checks the results comparing them with the ones stored in the detect files in
35// the directory: resources/audio_processing/transient/
36// The files contain all the results in double precision (Little endian).
37// The audio files used with different sample rates are stored in the same
38// directory.
39#if defined(WEBRTC_IOS)
40TEST(TransientDetectorTest, DISABLED_CorrectnessBasedOnFiles) {
41#else
42TEST(TransientDetectorTest, CorrectnessBasedOnFiles) {
43#endif
44  for (size_t i = 0; i < kNumberOfSampleRates; ++i) {
45    int sample_rate_hz = kSampleRatesHz[i];
46
47    // Prepare detect file.
48    std::stringstream detect_file_name;
49    detect_file_name << "audio_processing/transient/detect"
50                     << (sample_rate_hz / 1000) << "kHz";
51
52    rtc::scoped_ptr<FileWrapper> detect_file(FileWrapper::Create());
53
54    detect_file->OpenFile(
55        test::ResourcePath(detect_file_name.str(), "dat").c_str(),
56        true,    // Read only.
57        false,   // No loop.
58        false);  // No text.
59
60    bool file_opened = detect_file->Open();
61    ASSERT_TRUE(file_opened) << "File could not be opened.\n"
62          << detect_file_name.str().c_str();
63
64    // Prepare audio file.
65    std::stringstream audio_file_name;
66    audio_file_name << "audio_processing/transient/audio"
67                    << (sample_rate_hz / 1000) << "kHz";
68
69    rtc::scoped_ptr<FileWrapper> audio_file(FileWrapper::Create());
70
71    audio_file->OpenFile(
72        test::ResourcePath(audio_file_name.str(), "pcm").c_str(),
73        true,    // Read only.
74        false,   // No loop.
75        false);  // No text.
76
77    // Create detector.
78    TransientDetector detector(sample_rate_hz);
79
80    const size_t buffer_length = sample_rate_hz * ts::kChunkSizeMs / 1000;
81    rtc::scoped_ptr<float[]> buffer(new float[buffer_length]);
82
83    const float kTolerance = 0.02f;
84
85    size_t frames_read = 0;
86
87    while (ReadInt16FromFileToFloatBuffer(audio_file.get(),
88                                          buffer_length,
89                                          buffer.get()) == buffer_length) {
90      ++frames_read;
91
92      float detector_value =
93          detector.Detect(buffer.get(), buffer_length, NULL, 0);
94      double file_value;
95      ASSERT_EQ(1u, ReadDoubleBufferFromFile(detect_file.get(), 1, &file_value))
96          << "Detect test file is malformed.\n";
97
98      // Compare results with data from the matlab test file.
99      EXPECT_NEAR(file_value, detector_value, kTolerance) << "Frame: "
100          << frames_read;
101    }
102
103    detect_file->CloseFile();
104    audio_file->CloseFile();
105  }
106}
107
108}  // namespace webrtc
109