Add support for native FLAC reading

This commit is contained in:
rdb 2016-04-28 11:58:46 +02:00
parent 5feecd2243
commit 1c6f4c29c4
9 changed files with 3310 additions and 0 deletions

View File

@ -13,6 +13,8 @@
#include "config_movies.h"
#include "dconfig.h"
#include "flacAudio.h"
#include "flacAudioCursor.h"
#include "inkblotVideo.h"
#include "inkblotVideoCursor.h"
#include "microphoneAudio.h"
@ -75,6 +77,8 @@ init_libmovies() {
}
initialized = true;
FlacAudio::init_type();
FlacAudioCursor::init_type();
InkblotVideo::init_type();
InkblotVideoCursor::init_type();
MicrophoneAudio::init_type();
@ -93,6 +97,7 @@ init_libmovies() {
#endif
MovieTypeRegistry *reg = MovieTypeRegistry::get_global_ptr();
reg->register_audio_type(&FlacAudio::make, "flac");
reg->register_audio_type(&WavAudio::make, "wav wave");
#ifdef HAVE_VORBIS

2976
panda/src/movies/dr_flac.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flacAudio.I
* @author rdb
* @date 2016-04-27
*/

View File

@ -0,0 +1,64 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flacAudio.cxx
* @author rdb
* @date 2016-04-27
*/
#include "flacAudio.h"
#include "flacAudioCursor.h"
#include "virtualFileSystem.h"
#include "dcast.h"
TypeHandle FlacAudio::_type_handle;
/**
* xxx
*/
FlacAudio::
FlacAudio(const Filename &name) :
MovieAudio(name)
{
_filename = name;
}
/**
* xxx
*/
FlacAudio::
~FlacAudio() {
}
/**
* Open this audio, returning a MovieAudioCursor
*/
PT(MovieAudioCursor) FlacAudio::
open() {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
istream *stream = vfs->open_read_file(_filename, true);
if (stream == NULL) {
return NULL;
} else {
PT(FlacAudioCursor) cursor = new FlacAudioCursor(this, stream);
if (cursor == NULL || !cursor->_is_valid) {
return NULL;
} else {
return DCAST(MovieAudioCursor, cursor);
}
}
}
/**
* Obtains a MovieAudio that references a file.
*/
PT(MovieAudio) FlacAudio::
make(const Filename &name) {
return DCAST(MovieAudio, new FlacAudio(name));
}

View File

@ -0,0 +1,54 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flacAudio.h
* @author rdb
* @date 2016-04-27
*/
#ifndef FLACAUDIO_H
#define FLACAUDIO_H
#include "pandabase.h"
#include "movieAudio.h"
class FlacAudioCursor;
/**
* Reads FLAC audio files. Ogg-encapsulated FLAC files are not supported.
*/
class EXPCL_PANDA_MOVIES FlacAudio : public MovieAudio {
PUBLISHED:
FlacAudio(const Filename &name);
virtual ~FlacAudio();
virtual PT(MovieAudioCursor) open();
static PT(MovieAudio) make(const Filename &name);
private:
friend class FlacAudioCursor;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
MovieAudio::init_type();
register_type(_type_handle, "FlacAudio",
MovieAudio::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#endif // FLACAUDIO_H

View File

@ -0,0 +1,12 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file vorbisAudioCursor.I
* @author rdb
* @date 2013-08-23
*/

View File

@ -0,0 +1,120 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flacAudioCursor.cxx
* @author rdb
* @date 2013-08-23
*/
#include "flacAudioCursor.h"
#include "virtualFileSystem.h"
#define DR_FLAC_IMPLEMENTATION
#define DR_FLAC_NO_STDIO
extern "C" {
#include "dr_flac.h"
}
/**
* Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
*/
static size_t cb_read_proc(void *user, void *buffer, size_t size) {
istream *stream = (istream *)user;
nassertr(stream != NULL, false);
stream->read((char *)buffer, size);
if (stream->eof()) {
// Gracefully handle EOF.
stream->clear();
}
return stream->gcount();
}
/**
* Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
*/
static bool cb_seek_proc(void *user, int offset) {
istream *stream = (istream *)user;
nassertr(stream != NULL, false);
stream->seekg(offset, ios::cur);
return !stream->fail();
}
TypeHandle FlacAudioCursor::_type_handle;
/**
* Reads the .wav header from the indicated stream. This leaves the read
* pointer positioned at the start of the data.
*/
FlacAudioCursor::
FlacAudioCursor(FlacAudio *src, istream *stream) :
MovieAudioCursor(src),
_is_valid(false),
_drflac(NULL)
{
nassertv(stream != NULL);
nassertv(stream->good());
_drflac = drflac_open(&cb_read_proc, &cb_seek_proc, (void *)stream);
if (_drflac == NULL) {
movies_cat.error()
<< "Failed to open FLAC file.\n";
_is_valid = false;
}
_length = (_drflac->totalSampleCount / _drflac->channels) / (double)_drflac->sampleRate;
_audio_channels = _drflac->channels;
_audio_rate = _drflac->sampleRate;
_can_seek = true;
_can_seek_fast = _can_seek;
_is_valid = true;
}
/**
* xxx
*/
FlacAudioCursor::
~FlacAudioCursor() {
if (_drflac != NULL) {
drflac_close(_drflac);
}
}
/**
* Seeks to a target location. Afterward, the packet_time is guaranteed to be
* less than or equal to the specified time.
*/
void FlacAudioCursor::
seek(double t) {
t = max(t, 0.0);
uint64_t sample = t * _drflac->sampleRate;
if (drflac_seek_to_sample(_drflac, sample * _drflac->channels)) {
_last_seek = sample / (double)_drflac->sampleRate;
_samples_read = 0;
}
}
/**
* Read audio samples from the stream. N is the number of samples you wish to
* read. Your buffer must be equal in size to N * channels. Multiple-channel
* audio will be interleaved.
*/
void FlacAudioCursor::
read_samples(int n, PN_int16 *data) {
int desired = n * _audio_channels;
_samples_read += drflac_read_s16(_drflac, desired, data) / _audio_channels;
}

View File

@ -0,0 +1,65 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file flacAudioCursor.h
* @author rdb
* @date 2013-08-23
*/
#ifndef FLACAUDIOCURSOR_H
#define FLACAUDIOCURSOR_H
#include "pandabase.h"
#include "movieAudioCursor.h"
#define DR_FLAC_NO_STDIO
extern "C" {
#include "dr_flac.h"
}
class FlacAudio;
/**
* Interfaces with the libvorbisfile library to implement decoding of Ogg
* Vorbis audio files.
*/
class EXPCL_PANDA_MOVIES FlacAudioCursor : public MovieAudioCursor {
PUBLISHED:
FlacAudioCursor(FlacAudio *src, istream *stream);
virtual ~FlacAudioCursor();
virtual void seek(double offset);
public:
virtual void read_samples(int n, PN_int16 *data);
bool _is_valid;
protected:
drflac *_drflac;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
MovieAudioCursor::init_type();
register_type(_type_handle, "FlacAudioCursor",
MovieAudioCursor::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "flacAudioCursor.I"
#endif // FLACAUDIOCURSOR_H

View File

@ -1,4 +1,6 @@
#include "config_movies.cxx"
#include "flacAudio.cxx"
#include "flacAudioCursor.cxx"
#include "inkblotVideo.cxx"
#include "inkblotVideoCursor.cxx"
#include "microphoneAudio.cxx"