AudioBufferSourceNode.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (C) 2010, Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  17. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #ifndef AudioBufferSourceNode_h
  25. #define AudioBufferSourceNode_h
  26. #include "AudioBuffer.h"
  27. #include "AudioBus.h"
  28. #include "AudioParam.h"
  29. #include "AudioScheduledSourceNode.h"
  30. #include "PannerNode.h"
  31. #include <wtf/OwnArrayPtr.h>
  32. #include <wtf/PassRefPtr.h>
  33. #include <wtf/RefPtr.h>
  34. #include <wtf/Threading.h>
  35. namespace WebCore {
  36. class AudioContext;
  37. // AudioBufferSourceNode is an AudioNode representing an audio source from an in-memory audio asset represented by an AudioBuffer.
  38. // It generally will be used for short sounds which require a high degree of scheduling flexibility (can playback in rhythmically perfect ways).
  39. class AudioBufferSourceNode : public AudioScheduledSourceNode {
  40. public:
  41. static PassRefPtr<AudioBufferSourceNode> create(AudioContext*, float sampleRate);
  42. virtual ~AudioBufferSourceNode();
  43. // AudioNode
  44. virtual void process(size_t framesToProcess);
  45. virtual void reset();
  46. // setBuffer() is called on the main thread. This is the buffer we use for playback.
  47. // returns true on success.
  48. bool setBuffer(AudioBuffer*);
  49. AudioBuffer* buffer() { return m_buffer.get(); }
  50. // numberOfChannels() returns the number of output channels. This value equals the number of channels from the buffer.
  51. // If a new buffer is set with a different number of channels, then this value will dynamically change.
  52. unsigned numberOfChannels();
  53. // Play-state
  54. void startGrain(double when, double grainOffset);
  55. void startGrain(double when, double grainOffset, double grainDuration);
  56. #if ENABLE(LEGACY_WEB_AUDIO)
  57. void noteGrainOn(double when, double grainOffset, double grainDuration);
  58. #endif
  59. // Note: the attribute was originally exposed as .looping, but to be more consistent in naming with <audio>
  60. // and with how it's described in the specification, the proper attribute name is .loop
  61. // The old attribute is kept for backwards compatibility.
  62. bool loop() const { return m_isLooping; }
  63. void setLoop(bool looping) { m_isLooping = looping; }
  64. // Loop times in seconds.
  65. double loopStart() const { return m_loopStart; }
  66. double loopEnd() const { return m_loopEnd; }
  67. void setLoopStart(double loopStart) { m_loopStart = loopStart; }
  68. void setLoopEnd(double loopEnd) { m_loopEnd = loopEnd; }
  69. // Deprecated.
  70. bool looping();
  71. void setLooping(bool);
  72. AudioParam* gain() { return m_gain.get(); }
  73. AudioParam* playbackRate() { return m_playbackRate.get(); }
  74. // If a panner node is set, then we can incorporate doppler shift into the playback pitch rate.
  75. void setPannerNode(PannerNode*);
  76. void clearPannerNode();
  77. // If we are no longer playing, propogate silence ahead to downstream nodes.
  78. virtual bool propagatesSilence() const;
  79. // AudioScheduledSourceNode
  80. virtual void finish() OVERRIDE;
  81. private:
  82. AudioBufferSourceNode(AudioContext*, float sampleRate);
  83. virtual double tailTime() const OVERRIDE { return 0; }
  84. virtual double latencyTime() const OVERRIDE { return 0; }
  85. // Returns true on success.
  86. bool renderFromBuffer(AudioBus*, unsigned destinationFrameOffset, size_t numberOfFrames);
  87. // Render silence starting from "index" frame in AudioBus.
  88. inline bool renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess);
  89. // m_buffer holds the sample data which this node outputs.
  90. RefPtr<AudioBuffer> m_buffer;
  91. // Pointers for the buffer and destination.
  92. OwnArrayPtr<const float*> m_sourceChannels;
  93. OwnArrayPtr<float*> m_destinationChannels;
  94. // Used for the "gain" and "playbackRate" attributes.
  95. RefPtr<AudioParam> m_gain;
  96. RefPtr<AudioParam> m_playbackRate;
  97. // If m_isLooping is false, then this node will be done playing and become inactive after it reaches the end of the sample data in the buffer.
  98. // If true, it will wrap around to the start of the buffer each time it reaches the end.
  99. bool m_isLooping;
  100. double m_loopStart;
  101. double m_loopEnd;
  102. // m_virtualReadIndex is a sample-frame index into our buffer representing the current playback position.
  103. // Since it's floating-point, it has sub-sample accuracy.
  104. double m_virtualReadIndex;
  105. // Granular playback
  106. bool m_isGrain;
  107. double m_grainOffset; // in seconds
  108. double m_grainDuration; // in seconds
  109. // totalPitchRate() returns the instantaneous pitch rate (non-time preserving).
  110. // It incorporates the base pitch rate, any sample-rate conversion factor from the buffer, and any doppler shift from an associated panner node.
  111. double totalPitchRate();
  112. // m_lastGain provides continuity when we dynamically adjust the gain.
  113. float m_lastGain;
  114. // We optionally keep track of a panner node which has a doppler shift that is incorporated into
  115. // the pitch rate. We manually manage ref-counting because we want to use RefTypeConnection.
  116. PannerNode* m_pannerNode;
  117. // This synchronizes process() with setBuffer() which can cause dynamic channel count changes.
  118. mutable Mutex m_processLock;
  119. };
  120. } // namespace WebCore
  121. #endif // AudioBufferSourceNode_h