summaryrefslogtreecommitdiffstats
path: root/variablespeed/jni/variablespeed.h
blob: 5c6b45d0672d4f16b67e53ff1abe722f9801662c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#ifndef FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
#define FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_

#include <jni.h>

#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <SLES/OpenSLES_AndroidConfiguration.h>

#include <integral_types.h>
#include <utils/threads.h>

#include <profile_timer.h>
#include <decode_buffer.h>

#include <queue>
#include <stack>

namespace video_editing {
  class SolaTimeScaler;
}

// This is the audio engine class.
// It forms the bulk  of the variablespeed library.
// It should not be used directly, but rather used indirectly from the java
// native methods.
class AudioEngine {
 public:
  AudioEngine(size_t channels, size_t sampleRate, size_t targetFrames,
      float windowDuration, float windowOverlapDuration,
      size_t maxPlayBufferCount, float initialRate, size_t decodeInitialSize,
      size_t decodeMaxSize, size_t startPositionMillis);
  virtual ~AudioEngine();

  bool PlayUri(const char* uri);
  bool PlayFileDescriptor(int fd, int64 offset, int64 length);
  void SetVariableSpeed(float speed);
  void RequestStart();
  void RequestStop();
  int GetCurrentPosition();
  int GetTotalDuration();

  void DecodingBufferQueueCallback(
      SLAndroidSimpleBufferQueueItf queueItf, void *context);
  void DecodingEventCallback(SLPlayItf caller, SLuint32 event);
  void PrefetchEventCallback(SLPrefetchStatusItf caller, SLuint32 event);
  void PlayingBufferQueueCallback();

  static AudioEngine* GetEngine();
  static void SetEngine(AudioEngine* engine);
  static void DeleteEngine();

 private:
  bool PlayFromThisSource(const SLDataSource& audioSrc);
  void EnqueueMoreAudioIfNecessary(SLAndroidSimpleBufferQueueItf bufferQueue);
  bool EnqueueNextBufferOfAudio(SLAndroidSimpleBufferQueueItf bufferQueue);
  void PrefetchDurationSampleRateAndChannels(
      SLPlayItf playItf, SLPrefetchStatusItf prefetchItf);
  video_editing::SolaTimeScaler* GetTimeScaler();
  bool Finished();
  bool GetWasStartRequested();
  bool GetWasStopRequested();
  void ClearRequestStart();
  void SetEndOfDecoderReached();
  bool GetEndOfDecoderReached();
  bool DecodeBufferTooFull();
  void ClearDecodeBuffer();
  bool IsDecodeBufferEmpty();
  bool GetHasReachedPlayingBuffersLimit();

  // The single global audio engine instance.
  static AudioEngine* audioEngine_;

  // Protects access to the shared decode buffer.
  android::Mutex decodeBufferLock_;
  // Buffer into which we put the audio data as we decode.
  // Protected by decodeBufferLock_.
  DecodeBuffer decodeBuffer_;

  // Protects access to the playingBuffers_ and freeBuffers_.
  android::Mutex playBufferLock_;
  // The buffers we're using for playback.
  std::queue<int16*> playingBuffers_;
  std::stack<int16*> freeBuffers_;

  // The time scaler.
  video_editing::SolaTimeScaler* timeScaler_;

  // The frame buffer, used for converting between PCM data and float for
  // time scaler.
  float* floatBuffer_;
  float* injectBuffer_;

  size_t channels_;
  size_t sampleRate_;
  SLuint32 slSampleRate_;
  SLuint32 slOutputChannels_;
  size_t targetFrames_;
  float windowDuration_;
  float windowOverlapDuration_;
  size_t maxPlayBufferCount_;
  float initialRate_;
  size_t startPositionMillis_;

  // The prefetch callback signal, for letting the prefetch callback method
  // indicate when it is done.
  android::Mutex prefetchLock_;
  android::Condition prefetchCondition_;

  // Protects access to the CallbackContext object.
  // I don't believe this to be necessary, I think that it's thread-confined,
  // but it also won't do any harm.
  android::Mutex callbackLock_;

  // Protects access to the shared member variables below.
  android::Mutex lock_;
  // Protected by lock_.
  // Stores the total duration of the track.
  SLmillisecond totalDurationMs_;
  // Protected by lock_.
  // Set externally via RequestStart(), this determines when we begin to
  // playback audio.
  // Until this is set to true, our audio player will remain stopped.
  bool startRequested_;
  // Protected by lock_.
  // Set externally via RequestStop(), this tells us top stop playing
  // and therefore shut everything down.
  bool stopRequested_;
  // Protected by lock_.
  // This is set to true once we reach the end of the decoder stream.
  bool finishedDecoding_;

  DISALLOW_COPY_AND_ASSIGN(AudioEngine);
};

#endif  // FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_