spek

Acoustic spectrum analyser
git clone http://git.hanabi.in/repos/spek.git
Log | Files | Refs | README

commit d683b008973e88b80ce743ec5f3a592a6a16fd43
parent 166d31e69398dcfb423980aa408b8f2f6cb53832
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date:   Sat, 10 Jul 2010 12:10:15 +1000

Use av_malloc to allocate audio buffers

libavcodec crashes on Windows when using the usual malloc,
av_malloc makes sure the allocated buffer is properly aligned.

Diffstat:
Msrc/spek-audio.c | 10+++++++---
Msrc/spek-audio.h | 7+++----
Msrc/spek-pipeline.vala | 6++----
Mvapi/spek-audio.vapi | 4++--
4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/spek-audio.c b/src/spek-audio.c @@ -77,7 +77,6 @@ SpekAudioContext * spek_audio_open (const char *file_name) { cx->error = _("No audio channels"); return cx; } - cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; if (avcodec_open (cx->codec_context, cx->codec) < 0) { cx->error = _("Cannot open decoder"); return cx; @@ -103,6 +102,8 @@ SpekAudioContext * spek_audio_open (const char *file_name) { cx->error = _("Unsupported sample format"); return cx; } + cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; + cx->buffer = av_malloc (cx->buffer_size); av_init_packet (&cx->packet); cx->offset = 0; return cx; @@ -116,7 +117,7 @@ void spek_audio_start (SpekAudioContext *cx, gint samples) { cx->error_per_interval = (cx->stream->duration * rate) % cx->error_base; } -gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer) { +gint spek_audio_read (SpekAudioContext *cx) { gint buffer_size; gint len; gint res; @@ -129,7 +130,7 @@ gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer) { while (cx->packet.size > 0) { buffer_size = cx->buffer_size; len = avcodec_decode_audio3 ( - cx->codec_context, (int16_t *) buffer, &buffer_size, &cx->packet); + cx->codec_context, (int16_t *) cx->buffer, &buffer_size, &cx->packet); if (len < 0) { /* Error, skip the frame. */ cx->packet.size = 0; @@ -171,6 +172,9 @@ void spek_audio_close (SpekAudioContext *cx) { if (cx->codec_name != NULL) { g_free (cx->codec_name); } + if (cx->buffer) { + av_free (cx->buffer); + } if (cx->packet.data) { cx->packet.data -= cx->offset; cx->packet.size += cx->offset; diff --git a/src/spek-audio.h b/src/spek-audio.h @@ -30,6 +30,7 @@ typedef struct { AVCodecContext *codec_context; AVStream *stream; AVCodec *codec; + gint buffer_size; AVPacket packet; gint offset; @@ -44,7 +45,7 @@ typedef struct { gboolean fp; /* floating-point sample representation */ gint channels; gdouble duration; - gint buffer_size; /* minimum buffer size for spek_audio_read() */ + guint8 *buffer; gint64 frames_per_interval; gint64 error_per_interval; gint64 error_base; @@ -64,10 +65,8 @@ void spek_audio_start (SpekAudioContext *cx, gint samples); /* Read and decode the opened audio stream. * Returns -1 on error, 0 if there's nothing left to read * or the number of bytes decoded into the buffer. - * The buffer must be allocated (and later freed) by the caller, - * minimum size is `buffer_size`. */ -gint spek_audio_read (SpekAudioContext *cx, guint8 *buffer); +gint spek_audio_read (SpekAudioContext *cx); /* Closes the file opened with spek_audio_open, * frees all allocated buffers and the context diff --git a/src/spek-pipeline.vala b/src/spek-pipeline.vala @@ -36,7 +36,6 @@ namespace Spek { private int threshold; private Callback cb; - private uint8[] buffer; private Fft.Plan fft; private int nfft; // Size of the FFT transform. private const int NFFT = 64; // Number of FFTs to pre-fetch. @@ -89,7 +88,6 @@ namespace Spek { } this.sample_rate = cx.sample_rate; - this.buffer = new uint8[cx.buffer_size]; this.nfft = 2 * bands - 2; this.fft = new Fft.Plan (nfft, threshold); this.input_size = nfft * (NFFT * 2 + 1); @@ -140,10 +138,10 @@ namespace Spek { return null; } - while ((size = cx.read (this.buffer)) > 0) { + while ((size = cx.read ()) > 0) { lock (quit) if (quit) break; - uint8 *buffer = (uint8 *) this.buffer; + uint8 *buffer = (uint8 *) cx.buffer; while (size >= block_size) { input[pos] = average_input (buffer); buffer += block_size; diff --git a/vapi/spek-audio.vapi b/vapi/spek-audio.vapi @@ -13,7 +13,7 @@ namespace Spek.Audio { public bool fp; public int channels; public double duration; - public int buffer_size; + public uint8 *buffer; public int64 frames_per_interval; public int64 error_per_interval; public int64 error_base; @@ -23,7 +23,7 @@ namespace Spek.Audio { [CCode (cname = "spek_audio_start")] public int start (int samples); [CCode (cname = "spek_audio_read")] - public int read ([CCode (array_length = false)] uint8[] buffer); + public int read (); } public static void init (); }