Panda3D
flacAudioCursor.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file flacAudioCursor.cxx
10  * @author rdb
11  * @date 2013-08-23
12  */
13 
14 #include "flacAudioCursor.h"
15 #include "flacAudio.h"
16 #include "virtualFileSystem.h"
17 #include "config_movies.h"
18 
19 #define DR_FLAC_IMPLEMENTATION
20 extern "C" {
21  #include "dr_flac.h"
22 }
23 
24 /**
25  * Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
26  */
27 static size_t cb_read_proc(void *user, void *buffer, size_t size) {
28  std::istream *stream = (std::istream *)user;
29  nassertr(stream != nullptr, false);
30 
31  stream->read((char *)buffer, size);
32 
33  if (stream->eof()) {
34  // Gracefully handle EOF.
35  stream->clear();
36  }
37 
38  return stream->gcount();
39 }
40 
41 /**
42  * Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
43  */
44 static bool cb_seek_proc(void *user, int offset) {
45  std::istream *stream = (std::istream *)user;
46  nassertr(stream != nullptr, false);
47 
48  stream->seekg(offset, std::ios::cur);
49  return !stream->fail();
50 }
51 
52 TypeHandle FlacAudioCursor::_type_handle;
53 
54 /**
55  * Reads the .wav header from the indicated stream. This leaves the read
56  * pointer positioned at the start of the data.
57  */
59 FlacAudioCursor(FlacAudio *src, std::istream *stream) :
60  MovieAudioCursor(src),
61  _is_valid(false),
62  _drflac(nullptr),
63  _stream(stream)
64 {
65  nassertv(stream != nullptr);
66  nassertv(stream->good());
67 
68  _drflac = drflac_open(&cb_read_proc, &cb_seek_proc, (void *)stream);
69 
70  if (_drflac == nullptr) {
71  movies_cat.error()
72  << "Failed to open FLAC file.\n";
73  _is_valid = false;
74  }
75 
76  _length = (_drflac->totalSampleCount / _drflac->channels) / (double)_drflac->sampleRate;
77 
78  _audio_channels = _drflac->channels;
79  _audio_rate = _drflac->sampleRate;
80 
81  _can_seek = true;
82  _can_seek_fast = _can_seek;
83 
84  _is_valid = true;
85 }
86 
87 /**
88  * xxx
89  */
92  if (_drflac != nullptr) {
93  drflac_close(_drflac);
94  }
95  if (_stream != nullptr) {
97  }
98 }
99 
100 /**
101  * Seeks to a target location. Afterward, the packet_time is guaranteed to be
102  * less than or equal to the specified time.
103  */
105 seek(double t) {
106  t = std::max(t, 0.0);
107 
108  uint64_t sample = t * _drflac->sampleRate;
109 
110  if (drflac_seek_to_sample(_drflac, sample * _drflac->channels)) {
111  _last_seek = sample / (double)_drflac->sampleRate;
112  _samples_read = 0;
113  }
114 }
115 
116 /**
117  * Read audio samples from the stream. N is the number of samples you wish to
118  * read. Your buffer must be equal in size to N * channels. Multiple-channel
119  * audio will be interleaved.
120  */
122 read_samples(int n, int16_t *data) {
123  int desired = n * _audio_channels;
124  _samples_read += drflac_read_s16(_drflac, desired, data) / _audio_channels;
125 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
virtual void read_samples(int n, int16_t *data)
Read audio samples from the stream.
virtual ~FlacAudioCursor()
xxx
A MovieAudio is actually any source that provides a sequence of audio samples.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void seek(double offset)
Seeks to a target location.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Reads FLAC audio files.
Definition: flacAudio.h:27
FlacAudioCursor(FlacAudio *src, std::istream *stream)
Reads the .wav header from the indicated stream.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.