diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-10-20 18:39:15 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-10-20 20:05:26 +0100 |
| commit | e9ca66f0d8897739cdef22f5011e0866f5a3f741 (patch) | |
| tree | facd02deef05a75094efec59b7d04f26786d1599 /src | |
| parent | 068f8fe319aad390788bdea24ad21ef758d6dd03 (diff) | |
Clean up audio passing round a bit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/decoder.cc | 17 | ||||
| -rw-r--r-- | src/lib/decoder.h | 7 | ||||
| -rw-r--r-- | src/lib/encoder.h | 3 | ||||
| -rw-r--r-- | src/lib/imagemagick_encoder.h | 2 | ||||
| -rw-r--r-- | src/lib/j2k_still_encoder.h | 2 | ||||
| -rw-r--r-- | src/lib/j2k_wav_encoder.cc | 50 | ||||
| -rw-r--r-- | src/lib/j2k_wav_encoder.h | 5 | ||||
| -rw-r--r-- | src/lib/util.cc | 36 | ||||
| -rw-r--r-- | src/lib/util.h | 24 |
9 files changed, 92 insertions, 54 deletions
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 16d815a07..ee725c39d 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -192,12 +192,9 @@ Decoder::emit_audio (uint8_t* data, int size) { /* Deinterleave and convert to float */ - float* samples[_fs->audio_channels()]; int const total_samples = size / bytes_per_audio_sample(); int const frames = total_samples / _fs->audio_channels(); - for (int i = 0; i < _fs->audio_channels(); ++i) { - samples[i] = new float[frames]; - } + shared_ptr<AudioBuffers> audio (new AudioBuffers (_fs->audio_channels(), frames)); switch (audio_sample_format()) { case AV_SAMPLE_FMT_S16: @@ -211,7 +208,7 @@ Decoder::emit_audio (uint8_t* data, int size) /* signed sample */ int const os = ou >= 0x8000 ? (- 0x10000 + ou) : ou; /* float sample */ - samples[channel][sample] = float(os) / 0x8000; + audio->data(channel)[sample] = float(os) / 0x8000; ++channel; if (channel == _fs->audio_channels()) { @@ -228,7 +225,7 @@ Decoder::emit_audio (uint8_t* data, int size) { float* p = reinterpret_cast<float*> (data); for (int i = 0; i < _fs->audio_channels(); ++i) { - memcpy (samples[i], p, frames * sizeof(float)); + memcpy (audio->data(i), p, frames * sizeof(float)); p += frames; } } @@ -243,7 +240,7 @@ Decoder::emit_audio (uint8_t* data, int size) float const linear_gain = pow (10, _fs->audio_gain() / 20); for (int i = 0; i < _fs->audio_channels(); ++i) { for (int j = 0; j < frames; ++j) { - samples[i][j] *= linear_gain; + audio->data(i)[j] *= linear_gain; } } } @@ -251,11 +248,7 @@ Decoder::emit_audio (uint8_t* data, int size) /* Update the number of audio frames we've pushed to the encoder */ _audio_frames_processed += frames; - Audio (samples, frames); - - for (int i = 0; i < _fs->audio_channels(); ++i) { - delete[] samples[i]; - } + Audio (audio); } /** Called by subclasses to tell the world that some video data is ready. diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 14e602ace..85b256f5b 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -99,11 +99,8 @@ public: */ sigc::signal<void, boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle> > Video; - /** Emitted when some audio data is ready. - * First parameter is an array of pointers to deinterleaved, floating point sample data for each channel. - * Second parameter is the size of the data in frames (ie samples on each channel). - */ - sigc::signal<void, float**, int> Audio; + /** Emitted when some audio data is ready */ + sigc::signal<void, boost::shared_ptr<AudioBuffers> > Audio; protected: /** perform a single pass at our content */ diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 5dc0804c6..3317d30d1 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -37,6 +37,7 @@ class Options; class Image; class Log; class Subtitle; +class AudioBuffers; /** @class Encoder * @brief Parent class for classes which can encode video and audio frames. @@ -67,7 +68,7 @@ public: * @param d Array of pointers to floating point sample data for each channel. * @param s Number of frames (ie number of samples in each channel) */ - virtual void process_audio (float** d, int s) = 0; + virtual void process_audio (boost::shared_ptr<const AudioBuffers>) = 0; /** Called when a processing run has finished */ virtual void process_end () = 0; diff --git a/src/lib/imagemagick_encoder.h b/src/lib/imagemagick_encoder.h index 8e9c416ae..06f1723b1 100644 --- a/src/lib/imagemagick_encoder.h +++ b/src/lib/imagemagick_encoder.h @@ -38,6 +38,6 @@ public: void process_begin (int64_t audio_channel_layout, AVSampleFormat audio_sample_format) {} void process_video (boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle>); - void process_audio (float**, int) {} + void process_audio (boost::shared_ptr<const AudioBuffers>) {} void process_end () {} }; diff --git a/src/lib/j2k_still_encoder.h b/src/lib/j2k_still_encoder.h index 3c8f236ee..7e7719321 100644 --- a/src/lib/j2k_still_encoder.h +++ b/src/lib/j2k_still_encoder.h @@ -38,6 +38,6 @@ public: void process_begin (int64_t audio_channel_layout, AVSampleFormat audio_sample_format) {} void process_video (boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle>); - void process_audio (float**, int) {} + void process_audio (boost::shared_ptr<const AudioBuffers>) {} void process_end () {} }; diff --git a/src/lib/j2k_wav_encoder.cc b/src/lib/j2k_wav_encoder.cc index 7697a5e78..a83c283d7 100644 --- a/src/lib/j2k_wav_encoder.cc +++ b/src/lib/j2k_wav_encoder.cc @@ -303,13 +303,10 @@ J2KWAVEncoder::process_end () #if HAVE_SWRESAMPLE if (_swr_context) { - float* out[_fs->audio_channels()]; - for (int i = 0; i < _fs->audio_channels(); ++i) { - out[i] = new float[256]; - } + shared_ptr<AudioBuffers> out (new AudioBuffers (_fs->audio_channels(), 256)); while (1) { - int const frames = swr_convert (_swr_context, (uint8_t **) out, 256, 0, 0); + int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0); if (frames < 0) { throw EncodeError ("could not run sample-rate converter"); @@ -319,11 +316,7 @@ J2KWAVEncoder::process_end () break; } - write_audio (out, frames); - } - - for (int i = 0; i < _fs->audio_channels(); ++i) { - delete[] out[i]; + write_audio (out); } swr_free (&_swr_context); @@ -342,50 +335,43 @@ J2KWAVEncoder::process_end () } void -J2KWAVEncoder::process_audio (float** data, int frames) +J2KWAVEncoder::process_audio (shared_ptr<const AudioBuffers> audio) { - float* resampled[_fs->audio_channels()]; + shared_ptr<AudioBuffers> resampled; -#if HAVE_SWRESAMPLE +#if HAVE_SWRESAMPLE /* Maybe sample-rate convert */ if (_swr_context) { /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil (frames * _fs->target_sample_rate() / _fs->audio_sample_rate()) + 32; + int const max_resampled_frames = ceil (audio->frames() * _fs->target_sample_rate() / _fs->audio_sample_rate()) + 32; - /* Make a buffer to put the result in */ - for (int i = 0; i < _fs->audio_channels(); ++i) { - resampled[i] = new float[max_resampled_frames]; - } + resampled.reset (new AudioBuffers (_fs->audio_channels(), max_resampled_frames)); /* Resample audio */ - int const resampled_frames = swr_convert (_swr_context, (uint8_t **) resampled, max_resampled_frames, (uint8_t const **) data, frames); + int const resampled_frames = swr_convert ( + _swr_context, (uint8_t **) resampled->data(), max_resampled_frames, (uint8_t const **) audio->data(), audio->frames() + ); + if (resampled_frames < 0) { throw EncodeError ("could not run sample-rate converter"); } + resampled->set_frames (resampled_frames); + /* And point our variables at the resampled audio */ - data = resampled; - frames = resampled_frames; + audio = resampled; } #endif - write_audio (data, frames); - -#if HAVE_SWRESAMPLE - if (_swr_context) { - for (int i = 0; i < _fs->audio_channels(); ++i) { - delete[] resampled[i]; - } - } -#endif + write_audio (audio); } void -J2KWAVEncoder::write_audio (float** data, int frames) +J2KWAVEncoder::write_audio (shared_ptr<const AudioBuffers> audio) const { for (int i = 0; i < _fs->audio_channels(); ++i) { - sf_write_float (_sound_files[i], data[i], frames); + sf_write_float (_sound_files[i], audio->data(i), audio->frames()); } } diff --git a/src/lib/j2k_wav_encoder.h b/src/lib/j2k_wav_encoder.h index 3fdefcb38..2c18a5730 100644 --- a/src/lib/j2k_wav_encoder.h +++ b/src/lib/j2k_wav_encoder.h @@ -39,6 +39,7 @@ class DCPVideoFrame; class Image; class Log; class Subtitle; +class AudioBuffers; /** @class J2KWAVEncoder * @brief An encoder which writes JPEG2000 and WAV files. @@ -51,12 +52,12 @@ public: void process_begin (int64_t audio_channel_layout, AVSampleFormat audio_sample_format); void process_video (boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle>); - void process_audio (float**, int); + void process_audio (boost::shared_ptr<const AudioBuffers>); void process_end (); private: - void write_audio (float** data, int frames); + void write_audio (boost::shared_ptr<const AudioBuffers> audio) const; void encoder_thread (ServerDescription *); void close_sound_files (); void terminate_worker_threads (); diff --git a/src/lib/util.cc b/src/lib/util.cc index 3f5200ead..52a75474b 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -693,3 +693,39 @@ get_optional_int (multimap<string, string> const & kv, string k) return lexical_cast<int> (i->second); } + +AudioBuffers::AudioBuffers (int channels, int frames) + : _channels (channels) + , _frames (frames) +{ + _data = new float*[_channels]; + for (int i = 0; i < _channels; ++i) { + _data[i] = new float[frames]; + } +} + +AudioBuffers::~AudioBuffers () +{ + for (int i = 0; i < _channels; ++i) { + delete[] _data[i]; + } + + delete[] _data; +} + +float* +AudioBuffers::data (int c) const +{ + assert (c >= 0 && c < _channels); + return _data[c]; +} + +void +AudioBuffers::set_frames (int f) +{ + assert (f <= _frames); + _frames = f; +} + + + diff --git a/src/lib/util.h b/src/lib/util.h index f2087b3f0..c98049f62 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -203,5 +203,29 @@ private: int _buffer_data; }; +class AudioBuffers +{ +public: + AudioBuffers (int channels, int frames); + ~AudioBuffers (); + + float** data () const { + return _data; + } + + float* data (int) const; + + int frames () const { + return _frames; + } + + void set_frames (int f); + +private: + int _channels; + int _frames; + float** _data; +}; + #endif |
