1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *
4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Use of this source code is governed by a BSD-style license
5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  that can be found in the LICENSE file in the root of the source
6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  tree. An additional intellectual property rights grant can be found
7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  in the file PATENTS.  All contributing project authors may
8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  be found in the AUTHORS file in the root of the source tree.
9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * A wrapper for resampling a numerous amount of sampling combinations.
14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifndef WEBRTC_RESAMPLER_RESAMPLER_H_
17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#define WEBRTC_RESAMPLER_RESAMPLER_H_
18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "typedefs.h"
20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace webrtc
22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
24c55a96383497a772a307b346368133960b02ad03Eric Laurent// TODO(andrew): the implementation depends on the exact values of this enum.
25c55a96383497a772a307b346368133960b02ad03Eric Laurent// It should be rewritten in a less fragile way.
26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentenum ResamplerType
27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // 4 MSB = Number of channels
29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // 4 LSB = Synchronous or asynchronous
30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerSynchronous = 0x10,
32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerAsynchronous = 0x11,
33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerSynchronousStereo = 0x20,
34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerAsynchronousStereo = 0x21,
35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerInvalid = 0xff
36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent};
37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
38c55a96383497a772a307b346368133960b02ad03Eric Laurent// TODO(andrew): doesn't need to be part of the interface.
39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentenum ResamplerMode
40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode1To1,
42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode1To2,
43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode1To3,
44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode1To4,
45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode1To6,
46c55a96383497a772a307b346368133960b02ad03Eric Laurent    kResamplerMode1To12,
47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode2To3,
48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode2To11,
49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode4To11,
50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode8To11,
51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode11To16,
52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode11To32,
53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode2To1,
54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode3To1,
55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode4To1,
56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode6To1,
57c55a96383497a772a307b346368133960b02ad03Eric Laurent    kResamplerMode12To1,
58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode3To2,
59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode11To2,
60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode11To4,
61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    kResamplerMode11To8
62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent};
63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentclass Resampler
65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentpublic:
68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Resampler();
69c55a96383497a772a307b346368133960b02ad03Eric Laurent    // TODO(andrew): use an init function instead.
70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Resampler(int inFreq, int outFreq, ResamplerType type);
71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ~Resampler();
72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Reset all states
74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int Reset(int inFreq, int outFreq, ResamplerType type);
75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Reset all states if any parameter has changed
77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int ResetIfNeeded(int inFreq, int outFreq, ResamplerType type);
78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Synchronous resampling, all output samples are written to samplesOut
80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int Push(const WebRtc_Word16* samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent             int maxLen, int &outLen);
82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Asynchronous resampling, input
84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int Insert(WebRtc_Word16* samplesIn, int lengthIn);
85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Asynchronous resampling output, remaining samples are buffered
87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen);
88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentprivate:
90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Generic pointers since we don't know what states we'll need
91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    void* state1_;
92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    void* state2_;
93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    void* state3_;
94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Storage if needed
96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16* in_buffer_;
97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16* out_buffer_;
98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int in_buffer_size_;
99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int out_buffer_size_;
100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int in_buffer_size_max_;
101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int out_buffer_size_max_;
102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // State
104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int my_in_frequency_khz_;
105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int my_out_frequency_khz_;
106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ResamplerMode my_mode_;
107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ResamplerType my_type_;
108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Extra instance for stereo
110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Resampler* slave_left_;
111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Resampler* slave_right_;
112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent};
113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc
115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif // WEBRTC_RESAMPLER_RESAMPLER_H_
117