Panda3D
Loading...
Searching...
No Matches
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
20extern "C" {
21 #include "dr_flac.h"
22}
23
24/**
25 * Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
26 */
27static 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 */
44static 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
52TypeHandle 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 */
59FlacAudioCursor(FlacAudio *src, std::istream *stream) :
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 */
105seek(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 */
122read_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.