}
+/** @param frame_rate Frame rate in use; this is only used to check timing consistency of the incoming data */
void
-AudioRingBuffers::put (shared_ptr<const AudioBuffers> data, DCPTime time)
+AudioRingBuffers::put (shared_ptr<const AudioBuffers> data, DCPTime time, int frame_rate)
{
boost::mutex::scoped_lock lm (_mutex);
if (!_buffers.empty()) {
DCPOMATIC_ASSERT (_buffers.front().first->channels() == data->channels());
- if ((_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), 48000)) != time) {
+ if ((_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), frame_rate)) != time) {
cout << "bad put " << to_string(_buffers.back().second) << " " << _buffers.back().first->frames() << " " << to_string(time) << "\n";
}
- DCPOMATIC_ASSERT ((_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), 48000)) == time);
+ DCPOMATIC_ASSERT ((_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), frame_rate)) == time);
}
_buffers.push_back(make_pair(data, time));
public:
AudioRingBuffers ();
- void put (boost::shared_ptr<const AudioBuffers> data, DCPTime time);
+ void put (boost::shared_ptr<const AudioBuffers> data, DCPTime time, int frame_rate);
boost::optional<DCPTime> get (float* out, int channels, int frames);
void clear ();
, _fast (fast)
{
_player_video_connection = _player->Video.connect (bind (&Butler::video, this, _1, _2));
- _player_audio_connection = _player->Audio.connect (bind (&Butler::audio, this, _1, _2));
+ _player_audio_connection = _player->Audio.connect (bind (&Butler::audio, this, _1, _2, _3));
_player_text_connection = _player->Text.connect (bind (&Butler::text, this, _1, _2, _3, _4));
/* The butler must hear about things first, otherwise it might not sort out suspensions in time for
get_video() to be called in response to this signal.
}
void
-Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time)
+Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
{
{
boost::mutex::scoped_lock lm (_mutex);
}
boost::mutex::scoped_lock lm2 (_buffers_mutex);
- _audio.put (remap (audio, _audio_channels, _audio_mapping), time);
+ _audio.put (remap (audio, _audio_channels, _audio_mapping), time, frame_rate);
}
/** Try to get `frames' frames of audio and copy it into `out'. Silence
private:
void thread ();
void video (boost::shared_ptr<PlayerVideo> video, DCPTime time);
- void audio (boost::shared_ptr<AudioBuffers> audio, DCPTime time);
+ void audio (boost::shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate);
void text (PlayerText pt, TextType type, boost::optional<DCPTextTrack> track, DCPTimePeriod period);
bool should_run () const;
void prepare (boost::weak_ptr<PlayerVideo> video) const;
/* This audio must follow on from the previous */
DCPOMATIC_ASSERT (!_last_audio_time || time == *_last_audio_time);
- Audio (data, time);
+ Audio (data, time, _film->audio_frame_rate());
_last_audio_time = time + DCPTime::from_frames (data->frames(), _film->audio_frame_rate());
}
/** Emitted when a video frame is ready. These emissions happen in the correct order. */
boost::signals2::signal<void (boost::shared_ptr<PlayerVideo>, DCPTime)> Video;
- boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, DCPTime)> Audio;
+ boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, DCPTime, int)> Audio;
/** Emitted when a text is ready. This signal may be emitted considerably
* after the corresponding Video.
*/
data->data(j)[i] = value++;
}
}
- rb.put (data, DCPTime());
+ rb.put (data, DCPTime(), 48000);
BOOST_CHECK_EQUAL (rb.size(), 91);
/* Get part of it out */
data->data(j)[i] = value++;
}
}
- rb.put (data, DCPTime());
+ rb.put (data, DCPTime(), 48000);
BOOST_CHECK_EQUAL (rb.size(), 91);
/* Get part of it out */
data->data(j)[i] = value++;
}
}
- rb.put (data, DCPTime ());
+ rb.put (data, DCPTime(), 48000);
BOOST_CHECK_EQUAL (rb.size(), 91);
/* Get part of it out */