1b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org/*
2b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *
4b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org */
10b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
11b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org#ifndef WEBRTC_COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_
12b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org#define WEBRTC_COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_
13b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
145350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org#include <limits>
155350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org
165350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
17b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org#include "webrtc/typedefs.h"
18b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
19b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.orgnamespace webrtc {
20b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
215350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgtypedef std::numeric_limits<int16_t> limits_int16;
225350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org
235350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgstatic inline int16_t RoundToInt16(float v) {
245350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  const float kMaxRound = limits_int16::max() - 0.5f;
255350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  const float kMinRound = limits_int16::min() + 0.5f;
265350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  if (v > 0)
275350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    return v >= kMaxRound ? limits_int16::max() :
285350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org                            static_cast<int16_t>(v + 0.5f);
295350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  return v <= kMinRound ? limits_int16::min() :
305350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org                          static_cast<int16_t>(v - 0.5f);
3111a8868e8e4803e6375eb1bd2002351786f55ebcandrew@webrtc.org}
3211a8868e8e4803e6375eb1bd2002351786f55ebcandrew@webrtc.org
335350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// Scale (from [-1, 1]) and round to full-range int16 with clamping.
345350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgstatic inline int16_t ScaleAndRoundToInt16(float v) {
355350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  if (v > 0)
365350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    return v >= 1 ? limits_int16::max() :
375350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org                    static_cast<int16_t>(v * limits_int16::max() + 0.5f);
385350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  return v <= -1 ? limits_int16::min() :
395350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org                   static_cast<int16_t>(-v * limits_int16::min() - 0.5f);
403528ad9d28554d6373d8c72ff528f3fee216002eturaj@webrtc.org}
413528ad9d28554d6373d8c72ff528f3fee216002eturaj@webrtc.org
425350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// Scale to float [-1, 1].
435350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgstatic inline float ScaleToFloat(int16_t v) {
445350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  const float kMaxInt16Inverse = 1.f / limits_int16::max();
455350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  const float kMinInt16Inverse = 1.f / limits_int16::min();
465350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse);
4711a8868e8e4803e6375eb1bd2002351786f55ebcandrew@webrtc.org}
4811a8868e8e4803e6375eb1bd2002351786f55ebcandrew@webrtc.org
495350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// Round |size| elements of |src| to int16 with clamping and write to |dest|.
509f7856a56b7ad9bc72b61995bcfb5aa444c114bbkwiberg@webrtc.orgvoid RoundToInt16(const float* src, size_t size, int16_t* dest);
515350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org
525350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// Scale (from [-1, 1]) and round |size| elements of |src| to full-range int16
535350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// with clamping and write to |dest|.
549f7856a56b7ad9bc72b61995bcfb5aa444c114bbkwiberg@webrtc.orgvoid ScaleAndRoundToInt16(const float* src, size_t size, int16_t* dest);
555350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org
565350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org// Scale |size| elements of |src| to float [-1, 1] and write to |dest|.
579f7856a56b7ad9bc72b61995bcfb5aa444c114bbkwiberg@webrtc.orgvoid ScaleToFloat(const int16_t* src, size_t size, float* dest);
585350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org
59b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// Deinterleave audio from |interleaved| to the channel buffers pointed to
60b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// by |deinterleaved|. There must be sufficient space allocated in the
61b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// |deinterleaved| buffers (|num_channel| buffers with |samples_per_channel|
62b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// per buffer).
635350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgtemplate <typename T>
645350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgvoid Deinterleave(const T* interleaved, int samples_per_channel,
65a0d235763fdcf0820ec97bb51b94a01f547f8334andrew@webrtc.org                  int num_channels, T* const* deinterleaved) {
665350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  for (int i = 0; i < num_channels; ++i) {
675350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    T* channel = deinterleaved[i];
685350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    int interleaved_idx = i;
695350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    for (int j = 0; j < samples_per_channel; ++j) {
705350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org      channel[j] = interleaved[interleaved_idx];
715350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org      interleaved_idx += num_channels;
725350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    }
735350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  }
745350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org}
75b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
76b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// Interleave audio from the channel buffers pointed to by |deinterleaved| to
77b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// |interleaved|. There must be sufficient space allocated in |interleaved|
78b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org// (|samples_per_channel| * |num_channels|).
795350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgtemplate <typename T>
805350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.orgvoid Interleave(const T* const* deinterleaved, int samples_per_channel,
815350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org                int num_channels, T* interleaved) {
825350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  for (int i = 0; i < num_channels; ++i) {
835350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    const T* channel = deinterleaved[i];
845350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    int interleaved_idx = i;
855350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    for (int j = 0; j < samples_per_channel; ++j) {
865350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org      interleaved[interleaved_idx] = channel[j];
875350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org      interleaved_idx += num_channels;
885350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org    }
895350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org  }
905350e31941086c3861f12f8a4756066ee3137c63andrew@webrtc.org}
91b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
92b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org}  // namespace webrtc
93b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org
94b6fadb16521d2d174c19a6fa881523fced10c6c9andrew@webrtc.org#endif  // WEBRTC_COMMON_AUDIO_INCLUDE_AUDIO_UTIL_H_
95