mirror of
https://github.com/alexkay/spek.git
synced 2025-04-22 03:10:29 +03:00
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.
This commit is contained in:
parent
166d31e693
commit
d683b00897
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user