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 }
virtual void read_samples(int n, int16_t *data)
Read audio samples from the stream.
FlacAudioCursor(FlacAudio *src, std::istream *stream)
Reads the .wav header from the indicated stream.
virtual ~FlacAudioCursor()
xxx
virtual void seek(double offset)
Seeks to a target location.
Reads FLAC audio files.
Definition: flacAudio.h:27
A MovieAudio is actually any source that provides a sequence of audio samples.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.