spek

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

commit 8b7d3b5c2d9eb6996da5f3a355b3430671e18473
parent 4fc7070285c578096a8597b7a4b1dc10d55a2632
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date:   Sat,  2 Feb 2013 19:06:40 -0800

Use C++ everywhere

Diffstat:
MMakefile.am | 3+--
Mconfigure.ac | 3+--
Mlib/Makefile.am | 12++++++------
Dlib/spek-audio.c | 223-------------------------------------------------------------------------------
Alib/spek-audio.cc | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dlib/spek-fft.c | 64----------------------------------------------------------------
Alib/spek-fft.cc | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dlib/spek-palette.c | 61-------------------------------------------------------------
Alib/spek-palette.cc | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/spek-palette.h | 4++--
Dlib/spek-pipeline.c | 369-------------------------------------------------------------------------------
Alib/spek-pipeline.cc | 372+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dlib/spek-utils.c | 65-----------------------------------------------------------------
Alib/spek-utils.cc | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpo/spek.pot | 80++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Makefile.am | 18+++++++++---------
Msrc/spek-artwork.cc | 2+-
Asrc/spek-artwork.h | 32++++++++++++++++++++++++++++++++
Dsrc/spek-artwork.hh | 32--------------------------------
Msrc/spek-audio-desc.cc | 4+---
Asrc/spek-audio-desc.h | 28++++++++++++++++++++++++++++
Dsrc/spek-audio-desc.hh | 28----------------------------
Msrc/spek-events.cc | 2+-
Asrc/spek-events.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-events.hh | 53-----------------------------------------------------
Msrc/spek-platform.cc | 2+-
Asrc/spek-platform.h | 37+++++++++++++++++++++++++++++++++++++
Dsrc/spek-platform.hh | 37-------------------------------------
Msrc/spek-preferences-dialog.cc | 6+++---
Asrc/spek-preferences-dialog.h | 38++++++++++++++++++++++++++++++++++++++
Dsrc/spek-preferences-dialog.hh | 38--------------------------------------
Msrc/spek-preferences.cc | 4++--
Asrc/spek-preferences.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-preferences.hh | 47-----------------------------------------------
Msrc/spek-ruler.cc | 2+-
Asrc/spek-ruler.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-ruler.hh | 62--------------------------------------------------------------
Msrc/spek-spectrogram.cc | 12+++++-------
Asrc/spek-spectrogram.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-spectrogram.hh | 60------------------------------------------------------------
Msrc/spek-window.cc | 12+++++-------
Asrc/spek-window.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-window.hh | 51---------------------------------------------------
Msrc/spek.cc | 10++++------
Dtests/test-utils.c | 44--------------------------------------------
Atests/test-utils.cc | 44++++++++++++++++++++++++++++++++++++++++++++
Dtests/test.c | 26--------------------------
Atests/test.cc | 26++++++++++++++++++++++++++
48 files changed, 1354 insertions(+), 1353 deletions(-)

diff --git a/Makefile.am b/Makefile.am @@ -3,8 +3,7 @@ SUBDIRS = \ lib \ man \ po \ - src \ - tests + src EXTRA_DIST = \ INSTALL.md \ diff --git a/configure.ac b/configure.ac @@ -4,7 +4,7 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.11.1 foreign no-dist-gzip dist-xz]) AM_SILENT_RULES([yes]) -AC_PROG_CC_C99 +AC_LANG([C++]) AC_PROG_CXX AC_PROG_RANLIB AC_PROG_INSTALL @@ -71,7 +71,6 @@ AC_CONFIG_FILES([ man/spek.1 po/Makefile.in src/Makefile - tests/Makefile web/version ]) AC_OUTPUT diff --git a/lib/Makefile.am b/lib/Makefile.am @@ -1,20 +1,20 @@ noinst_LIBRARIES = libspek.a libspek_a_SOURCES = \ - spek-audio.c \ + spek-audio.cc \ spek-audio.h \ - spek-fft.c \ + spek-fft.cc \ spek-fft.h \ - spek-palette.c \ + spek-palette.cc \ spek-palette.h \ - spek-pipeline.c \ + spek-pipeline.cc \ spek-pipeline.h \ - spek-utils.c \ + spek-utils.cc \ spek-utils.h libspek_a_CPPFLAGS = \ -include config.h \ -pthread -libspek_a_CFLAGS = \ +libspek_a_CXXFLAGS = \ $(FFMPEG_CFLAGS) diff --git a/lib/spek-audio.c b/lib/spek-audio.c @@ -1,223 +0,0 @@ -/* spek-audio.c - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <string.h> - -#include <libavformat/avformat.h> -#include <libavcodec/avcodec.h> -#include <libavutil/mathematics.h> - -#include "spek-audio.h" - -struct spek_audio_context -{ - AVFormatContext *format_context; - int audio_stream; - AVCodecContext *codec_context; - AVStream *stream; - AVCodec *codec; - int buffer_size; - AVPacket *packet; - int offset; - - struct spek_audio_properties properties; -}; - - -void spek_audio_init() -{ - // TODO: register only audio decoders. - av_register_all(); -} - -const struct spek_audio_properties * spek_audio_get_properties(struct spek_audio_context *cx) -{ - return &cx->properties; -} - -struct spek_audio_context * spek_audio_open(const char *path) -{ - // TODO: malloc and initialise explicitely - struct spek_audio_context *cx = calloc(1, sizeof(struct spek_audio_context)); - - if (avformat_open_input(&cx->format_context, path, NULL, NULL) != 0) { - cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_FILE; - return cx; - } - if (avformat_find_stream_info(cx->format_context, NULL) < 0) { - // 24-bit APE returns an error but parses the stream info just fine. - if (cx->format_context->nb_streams <= 0) { - cx->properties.error = SPEK_AUDIO_NO_STREAMS; - return cx; - } - } - cx->audio_stream = -1; - for (int i = 0; i < cx->format_context->nb_streams; i++) { - if (cx->format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - cx->audio_stream = i; - break; - } - } - if (cx->audio_stream == -1) { - cx->properties.error = SPEK_AUDIO_NO_AUDIO; - return cx; - } - cx->stream = cx->format_context->streams[cx->audio_stream]; - cx->codec_context = cx->stream->codec; - cx->codec = avcodec_find_decoder(cx->codec_context->codec_id); - if (cx->codec == NULL) { - cx->properties.error = SPEK_AUDIO_NO_DECODER; - return cx; - } - // We can already fill in the stream info even if the codec won't be able to open it. - cx->properties.codec_name = strdup(cx->codec->long_name); - cx->properties.bit_rate = cx->codec_context->bit_rate; - cx->properties.sample_rate = cx->codec_context->sample_rate; - cx->properties.bits_per_sample = cx->codec_context->bits_per_raw_sample; - if (!cx->properties.bits_per_sample) { - // APE uses bpcs, FLAC uses bprs. - cx->properties.bits_per_sample = cx->codec_context->bits_per_coded_sample; - } - cx->properties.channels = cx->codec_context->channels; - if (cx->stream->duration != AV_NOPTS_VALUE) { - cx->properties.duration = cx->stream->duration * av_q2d(cx->stream->time_base); - } else if (cx->format_context->duration != AV_NOPTS_VALUE) { - cx->properties.duration = cx->format_context->duration / (double) AV_TIME_BASE; - } else { - cx->properties.error = SPEK_AUDIO_NO_DURATION; - return cx; - } - if (cx->properties.channels <= 0) { - cx->properties.error = SPEK_AUDIO_NO_CHANNELS; - return cx; - } - if (avcodec_open2(cx->codec_context, cx->codec, NULL) < 0) { - cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_DECODER; - return cx; - } - switch (cx->codec_context->sample_fmt) { - case AV_SAMPLE_FMT_S16: - cx->properties.width = 16; - cx->properties.fp = false; - break; - case AV_SAMPLE_FMT_S32: - cx->properties.width = 32; - cx->properties.fp = false; - break; - case AV_SAMPLE_FMT_FLT: - cx->properties.width = 32; - cx->properties.fp = true; - break; - case AV_SAMPLE_FMT_DBL: - cx->properties.width = 64; - cx->properties.fp = true; - break; - default: - cx->properties.error = SPEK_AUDIO_BAD_SAMPLE_FORMAT; - return cx; - } - cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; - cx->properties.buffer = av_malloc(cx->buffer_size); - cx->packet = av_mallocz(sizeof(AVPacket)); - av_init_packet(cx->packet); - cx->offset = 0; - return cx; -} - -void spek_audio_start(struct spek_audio_context *cx, int samples) -{ - int64_t rate = cx->properties.sample_rate * (int64_t) cx->stream->time_base.num; - int64_t duration = (int64_t) - (cx->properties.duration * cx->stream->time_base.den / cx->stream->time_base.num); - cx->properties.error_base = samples * (int64_t)cx->stream->time_base.den; - cx->properties.frames_per_interval = av_rescale_rnd( - duration, rate, cx->properties.error_base, AV_ROUND_DOWN); - cx->properties.error_per_interval = (duration * rate) % cx->properties.error_base; -} - -int spek_audio_read(struct spek_audio_context *cx) { - if (cx->properties.error) { - return -1; - } - - for (;;) { - while (cx->packet->size > 0) { - int buffer_size = cx->buffer_size; - int len = avcodec_decode_audio3( - cx->codec_context, (int16_t *)cx->properties.buffer, &buffer_size, cx->packet); - if (len < 0) { - // Error, skip the frame. - cx->packet->size = 0; - break; - } - cx->packet->data += len; - cx->packet->size -= len; - cx->offset += len; - if (buffer_size <= 0) { - // No data yet, get more frames. - continue; - } - // We have data, return it and come back for more later. - return buffer_size; - } - if (cx->packet->data) { - cx->packet->data -= cx->offset; - cx->packet->size += cx->offset; - cx->offset = 0; - av_free_packet (cx->packet); - } - - int res = 0; - while ((res = av_read_frame(cx->format_context, cx->packet)) >= 0) { - if (cx->packet->stream_index == cx->audio_stream) { - break; - } - av_free_packet(cx->packet); - } - if (res < 0) { - // End of file or error. - return 0; - } - } -} - -void spek_audio_close(struct spek_audio_context *cx) -{ - if (cx->properties.codec_name != NULL) { - free(cx->properties.codec_name); - } - if (cx->properties.buffer) { - av_free(cx->properties.buffer); - } - if (cx->packet) { - if (cx->packet->data) { - cx->packet->data -= cx->offset; - cx->packet->size += cx->offset; - cx->offset = 0; - av_free_packet(cx->packet); - } - av_free(cx->packet); - } - if (cx->codec_context != NULL) { - avcodec_close(cx->codec_context); - } - if (cx->format_context != NULL) { - av_close_input_file(cx->format_context); - } - free(cx); -} diff --git a/lib/spek-audio.cc b/lib/spek-audio.cc @@ -0,0 +1,227 @@ +/* spek-audio.cc + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> + +#define __STDC_CONSTANT_MACROS +extern "C" { +#include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#include <libavutil/mathematics.h> +} + +#include "spek-audio.h" + +struct spek_audio_context +{ + AVFormatContext *format_context; + int audio_stream; + AVCodecContext *codec_context; + AVStream *stream; + AVCodec *codec; + int buffer_size; + AVPacket *packet; + int offset; + + struct spek_audio_properties properties; +}; + + +void spek_audio_init() +{ + // TODO: register only audio decoders. + av_register_all(); +} + +const struct spek_audio_properties * spek_audio_get_properties(struct spek_audio_context *cx) +{ + return &cx->properties; +} + +struct spek_audio_context * spek_audio_open(const char *path) +{ + // TODO: malloc and initialise explicitely + struct spek_audio_context *cx = + (spek_audio_context *)calloc(1, sizeof(struct spek_audio_context)); + + if (avformat_open_input(&cx->format_context, path, NULL, NULL) != 0) { + cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_FILE; + return cx; + } + if (avformat_find_stream_info(cx->format_context, NULL) < 0) { + // 24-bit APE returns an error but parses the stream info just fine. + if (cx->format_context->nb_streams <= 0) { + cx->properties.error = SPEK_AUDIO_NO_STREAMS; + return cx; + } + } + cx->audio_stream = -1; + for (int i = 0; i < cx->format_context->nb_streams; i++) { + if (cx->format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + cx->audio_stream = i; + break; + } + } + if (cx->audio_stream == -1) { + cx->properties.error = SPEK_AUDIO_NO_AUDIO; + return cx; + } + cx->stream = cx->format_context->streams[cx->audio_stream]; + cx->codec_context = cx->stream->codec; + cx->codec = avcodec_find_decoder(cx->codec_context->codec_id); + if (cx->codec == NULL) { + cx->properties.error = SPEK_AUDIO_NO_DECODER; + return cx; + } + // We can already fill in the stream info even if the codec won't be able to open it. + cx->properties.codec_name = strdup(cx->codec->long_name); + cx->properties.bit_rate = cx->codec_context->bit_rate; + cx->properties.sample_rate = cx->codec_context->sample_rate; + cx->properties.bits_per_sample = cx->codec_context->bits_per_raw_sample; + if (!cx->properties.bits_per_sample) { + // APE uses bpcs, FLAC uses bprs. + cx->properties.bits_per_sample = cx->codec_context->bits_per_coded_sample; + } + cx->properties.channels = cx->codec_context->channels; + if (cx->stream->duration != AV_NOPTS_VALUE) { + cx->properties.duration = cx->stream->duration * av_q2d(cx->stream->time_base); + } else if (cx->format_context->duration != AV_NOPTS_VALUE) { + cx->properties.duration = cx->format_context->duration / (double) AV_TIME_BASE; + } else { + cx->properties.error = SPEK_AUDIO_NO_DURATION; + return cx; + } + if (cx->properties.channels <= 0) { + cx->properties.error = SPEK_AUDIO_NO_CHANNELS; + return cx; + } + if (avcodec_open2(cx->codec_context, cx->codec, NULL) < 0) { + cx->properties.error = SPEK_AUDIO_CANNOT_OPEN_DECODER; + return cx; + } + switch (cx->codec_context->sample_fmt) { + case AV_SAMPLE_FMT_S16: + cx->properties.width = 16; + cx->properties.fp = false; + break; + case AV_SAMPLE_FMT_S32: + cx->properties.width = 32; + cx->properties.fp = false; + break; + case AV_SAMPLE_FMT_FLT: + cx->properties.width = 32; + cx->properties.fp = true; + break; + case AV_SAMPLE_FMT_DBL: + cx->properties.width = 64; + cx->properties.fp = true; + break; + default: + cx->properties.error = SPEK_AUDIO_BAD_SAMPLE_FORMAT; + return cx; + } + cx->buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; + cx->properties.buffer = (uint8_t*)av_malloc(cx->buffer_size); + cx->packet = (AVPacket*)av_mallocz(sizeof(AVPacket)); + av_init_packet(cx->packet); + cx->offset = 0; + return cx; +} + +void spek_audio_start(struct spek_audio_context *cx, int samples) +{ + int64_t rate = cx->properties.sample_rate * (int64_t) cx->stream->time_base.num; + int64_t duration = (int64_t) + (cx->properties.duration * cx->stream->time_base.den / cx->stream->time_base.num); + cx->properties.error_base = samples * (int64_t)cx->stream->time_base.den; + cx->properties.frames_per_interval = av_rescale_rnd( + duration, rate, cx->properties.error_base, AV_ROUND_DOWN); + cx->properties.error_per_interval = (duration * rate) % cx->properties.error_base; +} + +int spek_audio_read(struct spek_audio_context *cx) { + if (cx->properties.error) { + return -1; + } + + for (;;) { + while (cx->packet->size > 0) { + int buffer_size = cx->buffer_size; + int len = avcodec_decode_audio3( + cx->codec_context, (int16_t *)cx->properties.buffer, &buffer_size, cx->packet); + if (len < 0) { + // Error, skip the frame. + cx->packet->size = 0; + break; + } + cx->packet->data += len; + cx->packet->size -= len; + cx->offset += len; + if (buffer_size <= 0) { + // No data yet, get more frames. + continue; + } + // We have data, return it and come back for more later. + return buffer_size; + } + if (cx->packet->data) { + cx->packet->data -= cx->offset; + cx->packet->size += cx->offset; + cx->offset = 0; + av_free_packet (cx->packet); + } + + int res = 0; + while ((res = av_read_frame(cx->format_context, cx->packet)) >= 0) { + if (cx->packet->stream_index == cx->audio_stream) { + break; + } + av_free_packet(cx->packet); + } + if (res < 0) { + // End of file or error. + return 0; + } + } +} + +void spek_audio_close(struct spek_audio_context *cx) +{ + if (cx->properties.codec_name != NULL) { + free(cx->properties.codec_name); + } + if (cx->properties.buffer) { + av_free(cx->properties.buffer); + } + if (cx->packet) { + if (cx->packet->data) { + cx->packet->data -= cx->offset; + cx->packet->size += cx->offset; + cx->offset = 0; + av_free_packet(cx->packet); + } + av_free(cx->packet); + } + if (cx->codec_context != NULL) { + avcodec_close(cx->codec_context); + } + if (cx->format_context != NULL) { + av_close_input_file(cx->format_context); + } + free(cx); +} diff --git a/lib/spek-fft.c b/lib/spek-fft.c @@ -1,64 +0,0 @@ -/* spek-fft.c - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <math.h> -#include <libavcodec/avfft.h> -#include <libavutil/mem.h> - -#include "spek-fft.h" - -struct spek_fft_plan * spek_fft_plan_new(int n) -{ - struct spek_fft_plan *p = malloc(sizeof(struct spek_fft_plan)); - p->input = av_mallocz(sizeof(float) * n); - p->output = av_mallocz(sizeof(float) * (n / 2 + 1)); - int bits = 0; - while (n) { - n >>= 1; - ++bits; - } - p->n = 1 << --bits; - p->cx = av_rdft_init(bits, DFT_R2C); - return p; -} - -void spek_fft_execute(struct spek_fft_plan *p) -{ - av_rdft_calc(p->cx, p->input); - - // Calculate magnitudes. - int n = p->n; - float n2 = n * n; - p->output[0] = 10.0f * log10f(p->input[0] * p->input[0] / n2); - p->output[n / 2] = 10.0f * log10f(p->input[1] * p->input[1] / n2); - for (int i = 1; i < n / 2; i++) { - float val = - p->input[i * 2] * p->input[i * 2] + - p->input[i * 2 + 1] * p->input[i * 2 + 1]; - val /= n2; - p->output[i] = 10.0f * log10f(val); - } -} - -void spek_fft_delete(struct spek_fft_plan *p) -{ - av_rdft_end(p->cx); - av_free(p->input); - av_free(p->output); - free(p); -} diff --git a/lib/spek-fft.cc b/lib/spek-fft.cc @@ -0,0 +1,68 @@ +/* spek-fft.cc + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <math.h> + +#define __STDC_CONSTANT_MACROS +extern "C" { +#include <libavcodec/avfft.h> +#include <libavutil/mem.h> +} + +#include "spek-fft.h" + +struct spek_fft_plan * spek_fft_plan_new(int n) +{ + struct spek_fft_plan *p = (spek_fft_plan*)malloc(sizeof(struct spek_fft_plan)); + p->input = (float*)av_mallocz(sizeof(float) * n); + p->output = (float*)av_mallocz(sizeof(float) * (n / 2 + 1)); + int bits = 0; + while (n) { + n >>= 1; + ++bits; + } + p->n = 1 << --bits; + p->cx = av_rdft_init(bits, DFT_R2C); + return p; +} + +void spek_fft_execute(struct spek_fft_plan *p) +{ + av_rdft_calc(p->cx, p->input); + + // Calculate magnitudes. + int n = p->n; + float n2 = n * n; + p->output[0] = 10.0f * log10f(p->input[0] * p->input[0] / n2); + p->output[n / 2] = 10.0f * log10f(p->input[1] * p->input[1] / n2); + for (int i = 1; i < n / 2; i++) { + float val = + p->input[i * 2] * p->input[i * 2] + + p->input[i * 2 + 1] * p->input[i * 2 + 1]; + val /= n2; + p->output[i] = 10.0f * log10f(val); + } +} + +void spek_fft_delete(struct spek_fft_plan *p) +{ + av_rdft_end(p->cx); + av_free(p->input); + av_free(p->output); + free(p); +} diff --git a/lib/spek-palette.c b/lib/spek-palette.c @@ -1,61 +0,0 @@ -/* spek-palette.c - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "spek-palette.h" - -// Modified version of Dan Bruton's algorithm: -// http://www.physics.sfasu.edu/astro/color/spectra.html -uint32_t spek_palette_spectrum(double level) -{ - level *= 0.6625; - double r = 0.0, g = 0.0, b = 0.0; - if (level >= 0 && level < 0.15) { - r = (0.15 - level) / (0.15 + 0.075); - g = 0.0; - b = 1.0; - } else if (level >= 0.15 && level < 0.275) { - r = 0.0; - g = (level - 0.15) / (0.275 - 0.15); - b = 1.0; - } else if (level >= 0.275 && level < 0.325) { - r = 0.0; - g = 1.0; - b = (0.325 - level) / (0.325 - 0.275); - } else if (level >= 0.325 && level < 0.5) { - r = (level - 0.325) / (0.5 - 0.325); - g = 1.0; - b = 0.0; - } else if (level >= 0.5 && level < 0.6625) { - r = 1.0; - g = (0.6625 - level) / (0.6625 - 0.5f); - b = 0.0; - } - - // Intensity correction. - double cf = 1.0; - if (level >= 0.0 && level < 0.1) { - cf = level / 0.1; - } - cf *= 255.0; - - // Pack RGB values into a 32-bit uint. - uint32_t rr = (uint32_t) (r * cf + 0.5); - uint32_t gg = (uint32_t) (g * cf + 0.5); - uint32_t bb = (uint32_t) (b * cf + 0.5); - return (rr << 16) + (gg << 8) + bb; -} diff --git a/lib/spek-palette.cc b/lib/spek-palette.cc @@ -0,0 +1,61 @@ +/* spek-palette.cc + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "spek-palette.h" + +// Modified version of Dan Bruton's algorithm: +// http://www.physics.sfasu.edu/astro/color/spectra.html +uint32_t spek_palette_spectrum(double level) +{ + level *= 0.6625; + double r = 0.0, g = 0.0, b = 0.0; + if (level >= 0 && level < 0.15) { + r = (0.15 - level) / (0.15 + 0.075); + g = 0.0; + b = 1.0; + } else if (level >= 0.15 && level < 0.275) { + r = 0.0; + g = (level - 0.15) / (0.275 - 0.15); + b = 1.0; + } else if (level >= 0.275 && level < 0.325) { + r = 0.0; + g = 1.0; + b = (0.325 - level) / (0.325 - 0.275); + } else if (level >= 0.325 && level < 0.5) { + r = (level - 0.325) / (0.5 - 0.325); + g = 1.0; + b = 0.0; + } else if (level >= 0.5 && level < 0.6625) { + r = 1.0; + g = (0.6625 - level) / (0.6625 - 0.5f); + b = 0.0; + } + + // Intensity correction. + double cf = 1.0; + if (level >= 0.0 && level < 0.1) { + cf = level / 0.1; + } + cf *= 255.0; + + // Pack RGB values into a 32-bit uint. + uint32_t rr = (uint32_t) (r * cf + 0.5); + uint32_t gg = (uint32_t) (g * cf + 0.5); + uint32_t bb = (uint32_t) (b * cf + 0.5); + return (rr << 16) + (gg << 8) + bb; +} diff --git a/lib/spek-palette.h b/lib/spek-palette.h @@ -16,8 +16,8 @@ * along with Spek. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SPEK_PALETTE_HH_ -#define SPEK_PALETTE_HH_ +#ifndef SPEK_PALETTE_H_ +#define SPEK_PALETTE_H_ #include <stdint.h> diff --git a/lib/spek-pipeline.c b/lib/spek-pipeline.c @@ -1,369 +0,0 @@ -/* spek-pipeline.c - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - * - * Conversion of decoded samples into an FFT-happy format is heavily - * influenced by GstSpectrum which is part of gst-plugins-good. - * The original code: - * (c) 1999 Erik Walthinsen <omega@cse.ogi.edu> - * (c) 2006 Stefan Kost <ensonic@users.sf.net> - * (c) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> - */ - -#include <assert.h> -#include <math.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> - -#include "spek-audio.h" -#include "spek-fft.h" - -#include "spek-pipeline.h" - -enum -{ - NFFT = 64 // Number of FFTs to pre-fetch. -}; - -struct spek_pipeline -{ - struct spek_audio_context *cx; - const struct spek_audio_properties *properties; - int bands; - int samples; - spek_pipeline_cb cb; - void *cb_data; - - struct spek_fft_plan *fft; - float *coss; // Pre-computed cos table. - int nfft; // Size of the FFT transform. - int input_size; - int input_pos; - float *input; - float *output; - - pthread_t reader_thread; - bool has_reader_thread; - pthread_mutex_t reader_mutex; - bool has_reader_mutex; - pthread_cond_t reader_cond; - bool has_reader_cond; - pthread_t worker_thread; - bool has_worker_thread; - pthread_mutex_t worker_mutex; - bool has_worker_mutex; - pthread_cond_t worker_cond; - bool has_worker_cond; - bool worker_done; - volatile bool quit; -}; - -// Forward declarations. -static void * reader_func(void *); -static void * worker_func(void *); -static void reader_sync(struct spek_pipeline *p, int pos); -static float average_input(const struct spek_pipeline *p, void *buffer); - -struct spek_pipeline * spek_pipeline_open( - const char *path, int bands, int samples, spek_pipeline_cb cb, void *cb_data) -{ - struct spek_pipeline *p = malloc(sizeof(struct spek_pipeline)); - p->cx = spek_audio_open(path); - p->properties = spek_audio_get_properties(p->cx); - p->bands = bands; - p->samples = samples; - p->cb = cb; - p->cb_data = cb_data; - - p->coss = NULL; - p->fft = NULL; - p->input = NULL; - p->output = NULL; - p->has_reader_thread = false; - p->has_reader_mutex = false; - p->has_reader_cond = false; - p->has_worker_thread = false; - p->has_worker_mutex = false; - p->has_worker_cond = false; - - if (!p->properties->error) { - p->nfft = 2 * bands - 2; - p->coss = malloc(p->nfft * sizeof(float)); - float cf = 2.0f * (float)M_PI / p->nfft; - for (int i = 0; i < p->nfft; ++i) { - p->coss[i] = cosf(cf * i); - } - p->fft = spek_fft_plan_new(p->nfft); - p->input_size = p->nfft * (NFFT * 2 + 1); - p->input = malloc(p->input_size * sizeof(float)); - p->output = malloc(bands * sizeof(float)); - spek_audio_start(p->cx, samples); - } - - return p; -} - -const struct spek_audio_properties * spek_pipeline_properties(struct spek_pipeline *pipeline) -{ - return pipeline->properties; -} - -void spek_pipeline_start(struct spek_pipeline *p) -{ - if (p->properties->error) return; - - p->input_pos = 0; - p->worker_done = false; - p->quit = false; - - p->has_reader_mutex = !pthread_mutex_init(&p->reader_mutex, NULL); - p->has_reader_cond = !pthread_cond_init(&p->reader_cond, NULL); - p->has_worker_mutex = !pthread_mutex_init(&p->worker_mutex, NULL); - p->has_worker_cond = !pthread_cond_init(&p->worker_cond, NULL); - - p->has_reader_thread = !pthread_create(&p->reader_thread, NULL, &reader_func, p); - if (!p->has_reader_thread) { - spek_pipeline_close(p); - } -} - -void spek_pipeline_close(struct spek_pipeline *p) -{ - if (p->has_reader_thread) { - p->quit = true; - pthread_join(p->reader_thread, NULL); - p->has_reader_thread = false; - } - if (p->has_worker_cond) { - pthread_cond_destroy(&p->worker_cond); - p->has_worker_cond = false; - } - if (p->has_worker_mutex) { - pthread_mutex_destroy(&p->worker_mutex); - p->has_worker_mutex = false; - } - if (p->has_reader_cond) { - pthread_cond_destroy(&p->reader_cond); - p->has_reader_cond = false; - } - if (p->has_reader_mutex) { - pthread_mutex_destroy(&p->reader_mutex); - p->has_reader_mutex = false; - } - if (p->output) { - free(p->output); - p->output = NULL; - } - if (p->input) { - free(p->input); - p->input = NULL; - } - if (p->fft) { - spek_fft_delete(p->fft); - p->fft = NULL; - } - if (p->coss) { - free(p->coss); - p->coss = NULL; - } - if (p->cx) { - spek_audio_close(p->cx); - p->cx = NULL; - } - free(p); -} - -static void * reader_func(void *pp) -{ - struct spek_pipeline *p = pp; - - p->has_worker_thread = !pthread_create(&p->worker_thread, NULL, &worker_func, p); - if (!p->has_worker_thread) { - return NULL; - } - - int pos = 0, prev_pos = 0; - int block_size = p->properties->width * p->properties->channels / 8; - int size; - while ((size = spek_audio_read(p->cx)) > 0) { - if (p->quit) break; - - uint8_t *buffer = p->properties->buffer; - while (size >= block_size) { - p->input[pos] = average_input(p, buffer); - buffer += block_size; - size -= block_size; - pos = (pos + 1) % p->input_size; - - // Wake up the worker if we have enough data. - if ((pos > prev_pos ? pos : pos + p->input_size) - prev_pos == p->nfft * NFFT) { - reader_sync(p, prev_pos = pos); - } - } - assert(size == 0); - } - - if (pos != prev_pos) { - // Process the remaining data. - reader_sync(p, pos); - } - - // Force the worker to quit. - reader_sync(p, -1); - pthread_join(p->worker_thread, NULL); - - // Notify the client. - p->cb(-1, NULL, p->cb_data); - return NULL; -} - -static void reader_sync(struct spek_pipeline *p, int pos) -{ - pthread_mutex_lock(&p->reader_mutex); - while (!p->worker_done) { - pthread_cond_wait(&p->reader_cond, &p->reader_mutex); - } - p->worker_done = false; - pthread_mutex_unlock(&p->reader_mutex); - - pthread_mutex_lock(&p->worker_mutex); - p->input_pos = pos; - pthread_cond_signal(&p->worker_cond); - pthread_mutex_unlock(&p->worker_mutex); -} - -static void * worker_func(void *pp) -{ - struct spek_pipeline *p = pp; - - int sample = 0; - int64_t frames = 0; - int64_t num_fft = 0; - int64_t acc_error = 0; - int head = 0, tail = 0; - int prev_head = 0; - - memset(p->output, 0, sizeof(float) * p->bands); - - while (true) { - pthread_mutex_lock(&p->reader_mutex); - p->worker_done = true; - pthread_cond_signal(&p->reader_cond); - pthread_mutex_unlock(&p->reader_mutex); - - pthread_mutex_lock(&p->worker_mutex); - while (tail == p->input_pos) { - pthread_cond_wait(&p->worker_cond, &p->worker_mutex); - } - tail = p->input_pos; - pthread_mutex_unlock(&p->worker_mutex); - - if (tail == -1) { - return NULL; - } - - while (true) { - head = (head + 1) % p->input_size; - if (head == tail) { - head = prev_head; - break; - } - frames++; - - // If we have enough frames for an FFT or we have - // all frames required for the interval run and FFT. - bool int_full = - acc_error < p->properties->error_base && - frames == p->properties->frames_per_interval; - bool int_over = - acc_error >= p->properties->error_base && - frames == 1 + p->properties->frames_per_interval; - - if (frames % p->nfft == 0 || ((int_full || int_over) && num_fft == 0)) { - prev_head = head; - for (int i = 0; i < p->nfft; i++) { - float val = p->input[(p->input_size + head - p->nfft + i) % p->input_size]; - // TODO: allow the user to chose the window function - // Hamming window. - // val *= 0.53836f - 0.46164f * coss[i]; - // Hann window. - val *= 0.5f * (1.0f - p->coss[i]); - p->fft->input[i] = val; - } - spek_fft_execute(p->fft); - num_fft++; - for (int i = 0; i < p->bands; i++) { - p->output[i] += p->fft->output[i]; - } - } - - // Do we have the FFTs for one interval? - if (int_full || int_over) { - if (int_over) { - acc_error -= p->properties->error_base; - } else { - acc_error += p->properties->error_per_interval; - } - - for (int i = 0; i < p->bands; i++) { - p->output[i] /= num_fft; - } - - if (sample == p->samples) break; - p->cb(sample++, p->output, p->cb_data); - - memset(p->output, 0, sizeof(float) * p->bands); - frames = 0; - num_fft = 0; - } - } - } -} - -static float average_input(const struct spek_pipeline *p, void *buffer) -{ - int channels = p->properties->channels; - float res = 0.0f; - if (p->properties->fp) { - if (p->properties->width == 32) { - float *b = buffer; - for (int i = 0; i < channels; i++) { - res += b[i]; - } - } else { - assert(p->properties->width == 64); - double *b = buffer; - for (int i = 0; i < channels; i++) { - res += (float) b[i]; - } - } - } else { - if (p->properties->width == 16) { - int16_t *b = buffer; - for (int i = 0; i < channels; i++) { - res += b[i] / (float) INT16_MAX; - } - } else { - assert (p->properties->width == 32); - int32_t *b = buffer; - for (int i = 0; i < channels; i++) { - res += b[i] / (float) INT32_MAX; - } - } - } - return res / channels; -} diff --git a/lib/spek-pipeline.cc b/lib/spek-pipeline.cc @@ -0,0 +1,372 @@ +/* spek-pipeline.cc + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + * + * Conversion of decoded samples into an FFT-happy format is heavily + * influenced by GstSpectrum which is part of gst-plugins-good. + * The original code: + * (c) 1999 Erik Walthinsen <omega@cse.ogi.edu> + * (c) 2006 Stefan Kost <ensonic@users.sf.net> + * (c) 2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> + */ + +#define __STDC_LIMIT_MACROS + +#include <assert.h> +#include <math.h> +#include <pthread.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "spek-audio.h" +#include "spek-fft.h" + +#include "spek-pipeline.h" + +enum +{ + NFFT = 64 // Number of FFTs to pre-fetch. +}; + +struct spek_pipeline +{ + struct spek_audio_context *cx; + const struct spek_audio_properties *properties; + int bands; + int samples; + spek_pipeline_cb cb; + void *cb_data; + + struct spek_fft_plan *fft; + float *coss; // Pre-computed cos table. + int nfft; // Size of the FFT transform. + int input_size; + int input_pos; + float *input; + float *output; + + pthread_t reader_thread; + bool has_reader_thread; + pthread_mutex_t reader_mutex; + bool has_reader_mutex; + pthread_cond_t reader_cond; + bool has_reader_cond; + pthread_t worker_thread; + bool has_worker_thread; + pthread_mutex_t worker_mutex; + bool has_worker_mutex; + pthread_cond_t worker_cond; + bool has_worker_cond; + bool worker_done; + volatile bool quit; +}; + +// Forward declarations. +static void * reader_func(void *); +static void * worker_func(void *); +static void reader_sync(struct spek_pipeline *p, int pos); +static float average_input(const struct spek_pipeline *p, void *buffer); + +struct spek_pipeline * spek_pipeline_open( + const char *path, int bands, int samples, spek_pipeline_cb cb, void *cb_data) +{ + struct spek_pipeline *p = (spek_pipeline*)malloc(sizeof(struct spek_pipeline)); + p->cx = spek_audio_open(path); + p->properties = spek_audio_get_properties(p->cx); + p->bands = bands; + p->samples = samples; + p->cb = cb; + p->cb_data = cb_data; + + p->coss = NULL; + p->fft = NULL; + p->input = NULL; + p->output = NULL; + p->has_reader_thread = false; + p->has_reader_mutex = false; + p->has_reader_cond = false; + p->has_worker_thread = false; + p->has_worker_mutex = false; + p->has_worker_cond = false; + + if (!p->properties->error) { + p->nfft = 2 * bands - 2; + p->coss = (float*)malloc(p->nfft * sizeof(float)); + float cf = 2.0f * (float)M_PI / p->nfft; + for (int i = 0; i < p->nfft; ++i) { + p->coss[i] = cosf(cf * i); + } + p->fft = spek_fft_plan_new(p->nfft); + p->input_size = p->nfft * (NFFT * 2 + 1); + p->input = (float*)malloc(p->input_size * sizeof(float)); + p->output = (float*)malloc(bands * sizeof(float)); + spek_audio_start(p->cx, samples); + } + + return p; +} + +const struct spek_audio_properties * spek_pipeline_properties(struct spek_pipeline *pipeline) +{ + return pipeline->properties; +} + +void spek_pipeline_start(struct spek_pipeline *p) +{ + if (p->properties->error) return; + + p->input_pos = 0; + p->worker_done = false; + p->quit = false; + + p->has_reader_mutex = !pthread_mutex_init(&p->reader_mutex, NULL); + p->has_reader_cond = !pthread_cond_init(&p->reader_cond, NULL); + p->has_worker_mutex = !pthread_mutex_init(&p->worker_mutex, NULL); + p->has_worker_cond = !pthread_cond_init(&p->worker_cond, NULL); + + p->has_reader_thread = !pthread_create(&p->reader_thread, NULL, &reader_func, p); + if (!p->has_reader_thread) { + spek_pipeline_close(p); + } +} + +void spek_pipeline_close(struct spek_pipeline *p) +{ + if (p->has_reader_thread) { + p->quit = true; + pthread_join(p->reader_thread, NULL); + p->has_reader_thread = false; + } + if (p->has_worker_cond) { + pthread_cond_destroy(&p->worker_cond); + p->has_worker_cond = false; + } + if (p->has_worker_mutex) { + pthread_mutex_destroy(&p->worker_mutex); + p->has_worker_mutex = false; + } + if (p->has_reader_cond) { + pthread_cond_destroy(&p->reader_cond); + p->has_reader_cond = false; + } + if (p->has_reader_mutex) { + pthread_mutex_destroy(&p->reader_mutex); + p->has_reader_mutex = false; + } + if (p->output) { + free(p->output); + p->output = NULL; + } + if (p->input) { + free(p->input); + p->input = NULL; + } + if (p->fft) { + spek_fft_delete(p->fft); + p->fft = NULL; + } + if (p->coss) { + free(p->coss); + p->coss = NULL; + } + if (p->cx) { + spek_audio_close(p->cx); + p->cx = NULL; + } + free(p); +} + +static void * reader_func(void *pp) +{ + struct spek_pipeline *p = (spek_pipeline*)pp; + + p->has_worker_thread = !pthread_create(&p->worker_thread, NULL, &worker_func, p); + if (!p->has_worker_thread) { + return NULL; + } + + int pos = 0, prev_pos = 0; + int block_size = p->properties->width * p->properties->channels / 8; + int size; + while ((size = spek_audio_read(p->cx)) > 0) { + if (p->quit) break; + + uint8_t *buffer = p->properties->buffer; + while (size >= block_size) { + p->input[pos] = average_input(p, buffer); + buffer += block_size; + size -= block_size; + pos = (pos + 1) % p->input_size; + + // Wake up the worker if we have enough data. + if ((pos > prev_pos ? pos : pos + p->input_size) - prev_pos == p->nfft * NFFT) { + reader_sync(p, prev_pos = pos); + } + } + assert(size == 0); + } + + if (pos != prev_pos) { + // Process the remaining data. + reader_sync(p, pos); + } + + // Force the worker to quit. + reader_sync(p, -1); + pthread_join(p->worker_thread, NULL); + + // Notify the client. + p->cb(-1, NULL, p->cb_data); + return NULL; +} + +static void reader_sync(struct spek_pipeline *p, int pos) +{ + pthread_mutex_lock(&p->reader_mutex); + while (!p->worker_done) { + pthread_cond_wait(&p->reader_cond, &p->reader_mutex); + } + p->worker_done = false; + pthread_mutex_unlock(&p->reader_mutex); + + pthread_mutex_lock(&p->worker_mutex); + p->input_pos = pos; + pthread_cond_signal(&p->worker_cond); + pthread_mutex_unlock(&p->worker_mutex); +} + +static void * worker_func(void *pp) +{ + struct spek_pipeline *p = (spek_pipeline*)pp; + + int sample = 0; + int64_t frames = 0; + int64_t num_fft = 0; + int64_t acc_error = 0; + int head = 0, tail = 0; + int prev_head = 0; + + memset(p->output, 0, sizeof(float) * p->bands); + + while (true) { + pthread_mutex_lock(&p->reader_mutex); + p->worker_done = true; + pthread_cond_signal(&p->reader_cond); + pthread_mutex_unlock(&p->reader_mutex); + + pthread_mutex_lock(&p->worker_mutex); + while (tail == p->input_pos) { + pthread_cond_wait(&p->worker_cond, &p->worker_mutex); + } + tail = p->input_pos; + pthread_mutex_unlock(&p->worker_mutex); + + if (tail == -1) { + return NULL; + } + + while (true) { + head = (head + 1) % p->input_size; + if (head == tail) { + head = prev_head; + break; + } + frames++; + + // If we have enough frames for an FFT or we have + // all frames required for the interval run and FFT. + bool int_full = + acc_error < p->properties->error_base && + frames == p->properties->frames_per_interval; + bool int_over = + acc_error >= p->properties->error_base && + frames == 1 + p->properties->frames_per_interval; + + if (frames % p->nfft == 0 || ((int_full || int_over) && num_fft == 0)) { + prev_head = head; + for (int i = 0; i < p->nfft; i++) { + float val = p->input[(p->input_size + head - p->nfft + i) % p->input_size]; + // TODO: allow the user to chose the window function + // Hamming window. + // val *= 0.53836f - 0.46164f * coss[i]; + // Hann window. + val *= 0.5f * (1.0f - p->coss[i]); + p->fft->input[i] = val; + } + spek_fft_execute(p->fft); + num_fft++; + for (int i = 0; i < p->bands; i++) { + p->output[i] += p->fft->output[i]; + } + } + + // Do we have the FFTs for one interval? + if (int_full || int_over) { + if (int_over) { + acc_error -= p->properties->error_base; + } else { + acc_error += p->properties->error_per_interval; + } + + for (int i = 0; i < p->bands; i++) { + p->output[i] /= num_fft; + } + + if (sample == p->samples) break; + p->cb(sample++, p->output, p->cb_data); + + memset(p->output, 0, sizeof(float) * p->bands); + frames = 0; + num_fft = 0; + } + } + } +} + +static float average_input(const struct spek_pipeline *p, void *buffer) +{ + int channels = p->properties->channels; + float res = 0.0f; + if (p->properties->fp) { + if (p->properties->width == 32) { + float *b = (float*)buffer; + for (int i = 0; i < channels; i++) { + res += b[i]; + } + } else { + assert(p->properties->width == 64); + double *b = (double*)buffer; + for (int i = 0; i < channels; i++) { + res += (float) b[i]; + } + } + } else { + if (p->properties->width == 16) { + int16_t *b = (int16_t*)buffer; + for (int i = 0; i < channels; i++) { + res += b[i] / (float) INT16_MAX; + } + } else { + assert (p->properties->width == 32); + int32_t *b = (int32_t*)buffer; + for (int i = 0; i < channels; i++) { + res += b[i] / (float) INT32_MAX; + } + } + } + return res / channels; +} diff --git a/lib/spek-utils.c b/lib/spek-utils.c @@ -1,65 +0,0 @@ -/* spek-utils.c - * - * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> -#include <limits.h> -#include <stdlib.h> - -#include "spek-utils.h" - -int spek_vercmp(const char *a, const char *b) -{ - assert(a && b); - - if (!*a && !*b) { - return 0; - } - if (!*a) { - return -1; - } - if (!*b) { - return 1; - } - - char *i, *j; - while(1) { - i = j = NULL; - long x = strtol(a, &i, 10); - long y = strtol(b, &j, 10); - - if (x < y) { - return -1; - } - if (x > y) { - return 1; - } - - if (!*i && !*j) { - return 0; - } - if (!*i) { - return -1; - } - if (!*j) { - return 1; - } - - a = i + 1; - b = j + 1; - } -} diff --git a/lib/spek-utils.cc b/lib/spek-utils.cc @@ -0,0 +1,65 @@ +/* spek-utils.cc + * + * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <limits.h> +#include <stdlib.h> + +#include "spek-utils.h" + +int spek_vercmp(const char *a, const char *b) +{ + assert(a && b); + + if (!*a && !*b) { + return 0; + } + if (!*a) { + return -1; + } + if (!*b) { + return 1; + } + + char *i, *j; + while(1) { + i = j = NULL; + long x = strtol(a, &i, 10); + long y = strtol(b, &j, 10); + + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + + if (!*i && !*j) { + return 0; + } + if (!*i) { + return -1; + } + if (!*j) { + return 1; + } + + a = i + 1; + b = j + 1; + } +} diff --git a/po/spek.pot b/po/spek.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-09-21 19:49-0700\n" +"POT-Creation-Date: 2013-02-02 19:03-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -34,179 +34,179 @@ msgstr "" msgid "View spectrograms of your audio files" msgstr "" -#: ../src/spek-audio-desc.cc:38 +#: ../src/spek-audio-desc.cc:36 #, c-format msgid "%d kbps" msgstr "" -#: ../src/spek-audio-desc.cc:41 +#: ../src/spek-audio-desc.cc:39 #, c-format msgid "%d Hz" msgstr "" -#: ../src/spek-audio-desc.cc:46 +#: ../src/spek-audio-desc.cc:44 #, c-format msgid "%d bit" msgid_plural "%d bits" msgstr[0] "" msgstr[1] "" -#: ../src/spek-audio-desc.cc:52 +#: ../src/spek-audio-desc.cc:50 #, c-format msgid "%d channel" msgid_plural "%d channels" msgstr[0] "" msgstr[1] "" -#: ../src/spek-audio-desc.cc:69 +#: ../src/spek-audio-desc.cc:67 msgid "Cannot open input file" msgstr "" -#: ../src/spek-audio-desc.cc:72 +#: ../src/spek-audio-desc.cc:70 msgid "Cannot find stream info" msgstr "" -#: ../src/spek-audio-desc.cc:75 +#: ../src/spek-audio-desc.cc:73 msgid "The file contains no audio streams" msgstr "" -#: ../src/spek-audio-desc.cc:78 +#: ../src/spek-audio-desc.cc:76 msgid "Cannot find decoder" msgstr "" -#: ../src/spek-audio-desc.cc:81 +#: ../src/spek-audio-desc.cc:79 msgid "Unknown duration" msgstr "" -#: ../src/spek-audio-desc.cc:84 +#: ../src/spek-audio-desc.cc:82 msgid "No audio channels" msgstr "" -#: ../src/spek-audio-desc.cc:87 +#: ../src/spek-audio-desc.cc:85 msgid "Cannot open decoder" msgstr "" -#: ../src/spek-audio-desc.cc:90 +#: ../src/spek-audio-desc.cc:88 msgid "Unsupported sample format" msgstr "" #. TRANSLATORS: first %s is the error message, second %s is stream description. -#: ../src/spek-audio-desc.cc:98 +#: ../src/spek-audio-desc.cc:96 #, c-format msgid "%s: %s" msgstr "" -#: ../src/spek-preferences-dialog.cc:58 +#: ../src/spek-preferences-dialog.cc:61 msgid "Preferences" msgstr "" -#: ../src/spek-preferences-dialog.cc:63 +#: ../src/spek-preferences-dialog.cc:66 msgid "(system default)" msgstr "" #. TRANSLATORS: The name of a section in the Preferences dialog. -#: ../src/spek-preferences-dialog.cc:70 +#: ../src/spek-preferences-dialog.cc:73 msgid "General" msgstr "" -#: ../src/spek-preferences-dialog.cc:79 +#: ../src/spek-preferences-dialog.cc:82 msgid "Language:" msgstr "" -#: ../src/spek-preferences-dialog.cc:95 +#: ../src/spek-preferences-dialog.cc:98 msgid "Check for &updates" msgstr "" -#: ../src/spek-spectrogram.cc:193 +#: ../src/spek-spectrogram.cc:191 #, c-format msgid "%d kHz" msgstr "" -#: ../src/spek-spectrogram.cc:198 +#: ../src/spek-spectrogram.cc:196 #, c-format msgid "%d dB" msgstr "" #. TRANSLATORS: keep "00" unchanged, it's used to calc the text width -#: ../src/spek-spectrogram.cc:304 +#: ../src/spek-spectrogram.cc:302 msgid "00 kHz" msgstr "" #. TRANSLATORS: keep "-00" unchanged, it's used to calc the text width -#: ../src/spek-spectrogram.cc:335 +#: ../src/spek-spectrogram.cc:333 msgid "-00 dB" msgstr "" -#: ../src/spek-window.cc:77 +#: ../src/spek-window.cc:75 msgid "Spek - Acoustic Spectrum Analyser" msgstr "" -#: ../src/spek-window.cc:97 +#: ../src/spek-window.cc:95 msgid "&File" msgstr "" -#: ../src/spek-window.cc:103 +#: ../src/spek-window.cc:101 msgid "&Edit" msgstr "" -#: ../src/spek-window.cc:107 ../src/spek-window.cc:112 +#: ../src/spek-window.cc:105 ../src/spek-window.cc:110 msgid "&Help" msgstr "" -#: ../src/spek-window.cc:135 +#: ../src/spek-window.cc:133 msgid "Help" msgstr "" -#: ../src/spek-window.cc:149 +#: ../src/spek-window.cc:147 msgid "A new version of Spek is available, click to download." msgstr "" #. TRANSLATORS: window title, %s is replaced with the file name -#: ../src/spek-window.cc:187 +#: ../src/spek-window.cc:185 #, c-format msgid "Spek - %s" msgstr "" -#: ../src/spek-window.cc:233 +#: ../src/spek-window.cc:231 msgid "All files" msgstr "" -#: ../src/spek-window.cc:235 +#: ../src/spek-window.cc:233 msgid "Audio files" msgstr "" -#: ../src/spek-window.cc:249 +#: ../src/spek-window.cc:247 msgid "Open File" msgstr "" -#: ../src/spek-window.cc:271 +#: ../src/spek-window.cc:269 msgid "PNG images" msgstr "" -#: ../src/spek-window.cc:277 +#: ../src/spek-window.cc:275 msgid "Save Spectrogram" msgstr "" #. Suggested name is <file_name>.png -#: ../src/spek-window.cc:285 +#: ../src/spek-window.cc:283 msgid "Untitled" msgstr "" #. TRANSLATORS: Add your name here -#: ../src/spek-window.cc:330 +#: ../src/spek-window.cc:329 msgid "translator-credits" msgstr "" -#: ../src/spek-window.cc:336 +#: ../src/spek-window.cc:335 msgid "Copyright (c) 2010-2012 Alexander Kojevnikov and contributors" msgstr "" -#: ../src/spek-window.cc:339 +#: ../src/spek-window.cc:338 msgid "Spek Website" msgstr "" #. TRANSLATORS: the %s is the package version. -#: ../src/spek.cc:100 +#: ../src/spek.cc:98 #, c-format msgid "Spek version %s" msgstr "" diff --git a/src/Makefile.am b/src/Makefile.am @@ -1,24 +1,24 @@ bin_PROGRAMS = spek spek_SOURCES = \ - spek-artwork.hh \ spek-artwork.cc \ + spek-artwork.h \ spek-audio-desc.cc \ - spek-audio-desc.hh \ + spek-audio-desc.h \ spek-events.cc \ - spek-events.hh \ + spek-events.h \ spek-platform.cc \ - spek-platform.hh \ + spek-platform.h \ spek-preferences-dialog.cc \ - spek-preferences-dialog.hh \ + spek-preferences-dialog.h \ spek-preferences.cc \ - spek-preferences.hh \ + spek-preferences.h \ spek-ruler.cc \ - spek-ruler.hh \ + spek-ruler.h \ spek-spectrogram.cc \ - spek-spectrogram.hh \ + spek-spectrogram.h \ spek-window.cc \ - spek-window.hh \ + spek-window.h \ spek.cc spek_CPPFLAGS = \ diff --git a/src/spek-artwork.cc b/src/spek-artwork.cc @@ -19,7 +19,7 @@ #include <wx/artprov.h> #include <wx/iconbndl.h> -#include "spek-artwork.hh" +#include "spek-artwork.h" class SpekArtProvider : public wxArtProvider { diff --git a/src/spek-artwork.h b/src/spek-artwork.h @@ -0,0 +1,32 @@ +/* spek-artwork.h + * + * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_ARTWORK_H_ +#define SPEK_ARTWORK_H_ + +#include <wx/string.h> + +#define ART_SPEK wxT("art-spek") +#define ART_OPEN wxT("art-open") +#define ART_SAVE wxT("art-save") +#define ART_HELP wxT("art-help") +#define ART_CLOSE wxT("art-close") + +void spek_artwork_init(); + +#endif diff --git a/src/spek-artwork.hh b/src/spek-artwork.hh @@ -1,32 +0,0 @@ -/* spek-artwork.hh - * - * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_ARTWORK_HH_ -#define SPEK_ARTWORK_HH_ - -#include <wx/string.h> - -#define ART_SPEK wxT("art-spek") -#define ART_OPEN wxT("art-open") -#define ART_SAVE wxT("art-save") -#define ART_HELP wxT("art-help") -#define ART_CLOSE wxT("art-close") - -void spek_artwork_init(); - -#endif diff --git a/src/spek-audio-desc.cc b/src/spek-audio-desc.cc @@ -19,11 +19,9 @@ #include <wx/arrstr.h> #include <wx/intl.h> -extern "C" { #include <spek-audio.h> -} -#include "spek-audio-desc.hh" +#include "spek-audio-desc.h" #define ngettext wxPLURAL diff --git a/src/spek-audio-desc.h b/src/spek-audio-desc.h @@ -0,0 +1,28 @@ +/* spek-audio-desc.h + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_AUDIO_DESC_H_ +#define SPEK_AUDIO_DESC_H_ + +#include <wx/string.h> + +struct spek_audio_properties; + +wxString spek_audio_desc(const struct spek_audio_properties *properties); + +#endif diff --git a/src/spek-audio-desc.hh b/src/spek-audio-desc.hh @@ -1,28 +0,0 @@ -/* spek-audio-desc.hh - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_AUDIO_DESC_HH_ -#define SPEK_AUDIO_DESC_HH_ - -#include <wx/string.h> - -struct spek_audio_properties; - -wxString spek_audio_desc(const struct spek_audio_properties *properties); - -#endif diff --git a/src/spek-events.cc b/src/spek-events.cc @@ -16,7 +16,7 @@ * along with Spek. If not, see <http://www.gnu.org/licenses/>. */ -#include "spek-events.hh" +#include "spek-events.h" //IMPLEMENT_DYNAMIC_CLASS(SpekHaveSampleEvent, wxEvent) DEFINE_EVENT_TYPE(SPEK_HAVE_SAMPLE) diff --git a/src/spek-events.h b/src/spek-events.h @@ -0,0 +1,53 @@ +/* spek-events.h + * + * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_EVENTS_H_ +#define SPEK_EVENTS_H_ + +#include <wx/wx.h> + +class SpekHaveSampleEvent: public wxEvent +{ +public: + SpekHaveSampleEvent(int bands, int sample, float *values, bool free_values); + SpekHaveSampleEvent(const SpekHaveSampleEvent& other); + ~SpekHaveSampleEvent(); + + int get_bands() const { return this->bands; } + int get_sample() const { return this->sample; } + const float *get_values() const { return this->values; } + + wxEvent *Clone() const { return new SpekHaveSampleEvent(*this); } +// DECLARE_DYNAMIC_CLASS(SpekHaveSampleEvent); + +private: + int bands; + int sample; + float *values; + bool free_values; +}; + +typedef void (wxEvtHandler::*SpekHaveSampleEventFunction)(SpekHaveSampleEvent&); + +DECLARE_EVENT_TYPE(SPEK_HAVE_SAMPLE, wxID_ANY) + +#define SPEK_EVT_HAVE_SAMPLE(fn) \ + DECLARE_EVENT_TABLE_ENTRY(SPEK_HAVE_SAMPLE, -1, -1, \ + (wxObjectEventFunction) (SpekHaveSampleEventFunction) &fn, (wxObject *) NULL ), + +#endif diff --git a/src/spek-events.hh b/src/spek-events.hh @@ -1,53 +0,0 @@ -/* spek-events.hh - * - * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_EVENTS_HH_ -#define SPEK_EVENTS_HH_ - -#include <wx/wx.h> - -class SpekHaveSampleEvent: public wxEvent -{ -public: - SpekHaveSampleEvent(int bands, int sample, float *values, bool free_values); - SpekHaveSampleEvent(const SpekHaveSampleEvent& other); - ~SpekHaveSampleEvent(); - - int get_bands() const { return this->bands; } - int get_sample() const { return this->sample; } - const float *get_values() const { return this->values; } - - wxEvent *Clone() const { return new SpekHaveSampleEvent(*this); } -// DECLARE_DYNAMIC_CLASS(SpekHaveSampleEvent); - -private: - int bands; - int sample; - float *values; - bool free_values; -}; - -typedef void (wxEvtHandler::*SpekHaveSampleEventFunction)(SpekHaveSampleEvent&); - -DECLARE_EVENT_TYPE(SPEK_HAVE_SAMPLE, wxID_ANY) - -#define SPEK_EVT_HAVE_SAMPLE(fn) \ - DECLARE_EVENT_TABLE_ENTRY(SPEK_HAVE_SAMPLE, -1, -1, \ - (wxObjectEventFunction) (SpekHaveSampleEventFunction) &fn, (wxObject *) NULL ), - -#endif diff --git a/src/spek-platform.cc b/src/spek-platform.cc @@ -26,7 +26,7 @@ #include <wx/stdpaths.h> #include <wx/utils.h> -#include "spek-platform.hh" +#include "spek-platform.h" void spek_platform_init() { diff --git a/src/spek-platform.h b/src/spek-platform.h @@ -0,0 +1,37 @@ +/* spek-platform.h + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_PLATFORM_H_ +#define SPEK_PLATFORM_H_ + +#include <wx/string.h> + +// Platform-specific initialisation code. +void spek_platform_init(); + +// Not quite XDG-compatible, but close enough. +wxString spek_platform_config_path(const wxString& app_name); + +// Setting non-default locale under GTK+ is tricky (see e.g. how FileZilla does it). We will +// just disable the language setting for GTK+ users and will always use the system locale. +bool spek_platform_can_change_language(); + +// Fonts are smaller on OSX. +double spek_platform_font_scale(); + +#endif diff --git a/src/spek-platform.hh b/src/spek-platform.hh @@ -1,37 +0,0 @@ -/* spek-platform.hh - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_PLATFORM_HH_ -#define SPEK_PLATFORM_HH_ - -#include <wx/string.h> - -// Platform-specific initialisation code. -void spek_platform_init(); - -// Not quite XDG-compatible, but close enough. -wxString spek_platform_config_path(const wxString& app_name); - -// Setting non-default locale under GTK+ is tricky (see e.g. how FileZilla does it). We will -// just disable the language setting for GTK+ users and will always use the system locale. -bool spek_platform_can_change_language(); - -// Fonts are smaller on OSX. -double spek_platform_font_scale(); - -#endif diff --git a/src/spek-preferences-dialog.cc b/src/spek-preferences-dialog.cc @@ -16,10 +16,10 @@ * along with Spek. If not, see <http://www.gnu.org/licenses/>. */ -#include "spek-platform.hh" -#include "spek-preferences.hh" +#include "spek-platform.h" +#include "spek-preferences.h" -#include "spek-preferences-dialog.hh" +#include "spek-preferences-dialog.h" // List all languages with a decent (e.g. 80%) number of translated // strings. Don't translate language names. Keep the first line intact. diff --git a/src/spek-preferences-dialog.h b/src/spek-preferences-dialog.h @@ -0,0 +1,38 @@ +/* spek-preferences-dialog.h + * + * Copyright (C) 2011-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_PREFERENCES_DIALOG_H_ +#define SPEK_PREFERENCES_DIALOG_H_ + +#include <wx/wx.h> + +class SpekPreferencesDialog : public wxDialog +{ +public: + SpekPreferencesDialog(wxWindow *parent); + +private: + void on_language(wxCommandEvent& event); + void on_check(wxCommandEvent& event); + + wxArrayString languages; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/src/spek-preferences-dialog.hh b/src/spek-preferences-dialog.hh @@ -1,38 +0,0 @@ -/* spek-preferences-dialog.hh - * - * Copyright (C) 2011-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_PREFERENCES_DIALOG_HH_ -#define SPEK_PREFERENCES_DIALOG_HH_ - -#include <wx/wx.h> - -class SpekPreferencesDialog : public wxDialog -{ -public: - SpekPreferencesDialog(wxWindow *parent); - -private: - void on_language(wxCommandEvent& event); - void on_check(wxCommandEvent& event); - - wxArrayString languages; - - DECLARE_EVENT_TABLE() -}; - -#endif diff --git a/src/spek-preferences.cc b/src/spek-preferences.cc @@ -18,9 +18,9 @@ #include <wx/string.h> -#include "spek-platform.hh" +#include "spek-platform.h" -#include "spek-preferences.hh" +#include "spek-preferences.h" SpekPreferences& SpekPreferences::get() { diff --git a/src/spek-preferences.h b/src/spek-preferences.h @@ -0,0 +1,47 @@ +/* spek-preferences.h + * + * Copyright (C) 2011-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_PREFERENCES_H_ +#define SPEK_PREFERENCES_H_ + +#include <wx/fileconf.h> +#include <wx/intl.h> + +class SpekPreferences +{ +public: + static SpekPreferences& get(); + + void init(); + bool get_check_update(); + void set_check_update(bool value); + long get_last_update(); + void set_last_update(long value); + wxString get_language(); + void set_language(const wxString& value); + +private: + SpekPreferences(); + SpekPreferences(const SpekPreferences&); + void operator=(const SpekPreferences&); + + wxLocale *locale; + wxFileConfig *config; +}; + +#endif diff --git a/src/spek-preferences.hh b/src/spek-preferences.hh @@ -1,47 +0,0 @@ -/* spek-preferences.hh - * - * Copyright (C) 2011-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_PREFERENCES_HH_ -#define SPEK_PREFERENCES_HH_ - -#include <wx/fileconf.h> -#include <wx/intl.h> - -class SpekPreferences -{ -public: - static SpekPreferences& get(); - - void init(); - bool get_check_update(); - void set_check_update(bool value); - long get_last_update(); - void set_last_update(long value); - wxString get_language(); - void set_language(const wxString& value); - -private: - SpekPreferences(); - SpekPreferences(const SpekPreferences&); - void operator=(const SpekPreferences&); - - wxLocale *locale; - wxFileConfig *config; -}; - -#endif diff --git a/src/spek-ruler.cc b/src/spek-ruler.cc @@ -18,7 +18,7 @@ #include <cmath> -#include "spek-ruler.hh" +#include "spek-ruler.h" SpekRuler::SpekRuler( int x, int y, Position pos, wxString sample_label, diff --git a/src/spek-ruler.h b/src/spek-ruler.h @@ -0,0 +1,62 @@ +/* spek-ruler.h + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_RULER_H_ +#define SPEK_RULER_H_ + +#include <wx/dc.h> +#include <wx/string.h> + +class SpekRuler +{ +public: + enum Position + { + TOP, + RIGHT, + BOTTOM, + LEFT + }; + + typedef wxString (*formatter_cb)(int unit); + + SpekRuler( + int x, int y, Position pos, wxString sample_label, + int *factors, int min_units, int max_units, double spacing, + double scale, double offset, formatter_cb formatter + ); + + void draw(wxDC& dc); + +protected: + void draw_tick(wxDC& dc, int tick); + + int x; + int y; + Position pos; + wxString sample_label; + int *factors; + int min_units; + int max_units; + double spacing; + double scale; + double offset; + formatter_cb formatter; +}; + +#endif diff --git a/src/spek-ruler.hh b/src/spek-ruler.hh @@ -1,62 +0,0 @@ -/* spek-ruler.hh - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_RULER_HH_ -#define SPEK_RULER_HH_ - -#include <wx/dc.h> -#include <wx/string.h> - -class SpekRuler -{ -public: - enum Position - { - TOP, - RIGHT, - BOTTOM, - LEFT - }; - - typedef wxString (*formatter_cb)(int unit); - - SpekRuler( - int x, int y, Position pos, wxString sample_label, - int *factors, int min_units, int max_units, double spacing, - double scale, double offset, formatter_cb formatter - ); - - void draw(wxDC& dc); - -protected: - void draw_tick(wxDC& dc, int tick); - - int x; - int y; - Position pos; - wxString sample_label; - int *factors; - int min_units; - int max_units; - double spacing; - double scale; - double offset; - formatter_cb formatter; -}; - -#endif diff --git a/src/spek-spectrogram.cc b/src/spek-spectrogram.cc @@ -20,19 +20,17 @@ #include <wx/dcbuffer.h> -extern "C" { #include <spek-audio.h> #include <spek-palette.h> #include <spek-pipeline.h> #include <spek-utils.h> -} -#include "spek-audio-desc.hh" -#include "spek-events.hh" -#include "spek-platform.hh" -#include "spek-ruler.hh" +#include "spek-audio-desc.h" +#include "spek-events.h" +#include "spek-platform.h" +#include "spek-ruler.h" -#include "spek-spectrogram.hh" +#include "spek-spectrogram.h" BEGIN_EVENT_TABLE(SpekSpectrogram, wxWindow) EVT_CHAR(SpekSpectrogram::on_char) diff --git a/src/spek-spectrogram.h b/src/spek-spectrogram.h @@ -0,0 +1,60 @@ +/* spek-spectrogram.h + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_SPECTROGRAM_H_ +#define SPEK_SPECTROGRAM_H_ + +#include <wx/wx.h> + +class SpekHaveSampleEvent; +struct spek_audio_properties; +struct spek_pipeline; + +class SpekSpectrogram : public wxWindow +{ +public: + SpekSpectrogram(wxFrame *parent); + ~SpekSpectrogram(); + void open(const wxString& path); + void save(const wxString& path); + +private: + void on_char(wxKeyEvent& evt); + void on_paint(wxPaintEvent& evt); + void on_size(wxSizeEvent& evt); + void on_have_sample(SpekHaveSampleEvent& evt); + void render(wxDC& dc); + + void start(); + void stop(); + + spek_pipeline *pipeline; + wxString path; + wxString desc; + double duration; + int sample_rate; + wxImage palette; + wxImage image; + int prev_width; + int urange; + int lrange; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/src/spek-spectrogram.hh b/src/spek-spectrogram.hh @@ -1,60 +0,0 @@ -/* spek-spectrogram.hh - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_SPECTROGRAM_HH_ -#define SPEK_SPECTROGRAM_HH_ - -#include <wx/wx.h> - -class SpekHaveSampleEvent; -struct spek_audio_properties; -struct spek_pipeline; - -class SpekSpectrogram : public wxWindow -{ -public: - SpekSpectrogram(wxFrame *parent); - ~SpekSpectrogram(); - void open(const wxString& path); - void save(const wxString& path); - -private: - void on_char(wxKeyEvent& evt); - void on_paint(wxPaintEvent& evt); - void on_size(wxSizeEvent& evt); - void on_have_sample(SpekHaveSampleEvent& evt); - void render(wxDC& dc); - - void start(); - void stop(); - - spek_pipeline *pipeline; - wxString path; - wxString desc; - double duration; - int sample_rate; - wxImage palette; - wxImage image; - int prev_width; - int urange; - int lrange; - - DECLARE_EVENT_TABLE() -}; - -#endif diff --git a/src/spek-window.cc b/src/spek-window.cc @@ -26,16 +26,14 @@ // WX on WIN doesn't like it when pthread.h is included first. #include <pthread.h> -extern "C" { #include <spek-utils.h> -} -#include "spek-artwork.hh" -#include "spek-preferences-dialog.hh" -#include "spek-preferences.hh" -#include "spek-spectrogram.hh" +#include "spek-artwork.h" +#include "spek-preferences-dialog.h" +#include "spek-preferences.h" +#include "spek-spectrogram.h" -#include "spek-window.hh" +#include "spek-window.h" DECLARE_EVENT_TYPE(SPEK_NOTIFY_EVENT, -1) DEFINE_EVENT_TYPE(SPEK_NOTIFY_EVENT) diff --git a/src/spek-window.h b/src/spek-window.h @@ -0,0 +1,51 @@ +/* spek-window.h + * + * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SPEK_WINDOW_H_ +#define SPEK_WINDOW_H_ + +#include <wx/wx.h> + +class SpekSpectrogram; + +class SpekWindow : public wxFrame +{ +public: + SpekWindow(const wxString& path); + void open(const wxString& path); + +private: + void on_open(wxCommandEvent& event); + void on_save(wxCommandEvent& event); + void on_exit(wxCommandEvent& event); + void on_preferences(wxCommandEvent& event); + void on_help(wxCommandEvent& event); + void on_about(wxCommandEvent& event); + void on_notify(wxCommandEvent& event); + void on_visit(wxCommandEvent& event); + void on_close(wxCommandEvent& event); + + SpekSpectrogram *spectrogram; + wxString path; + wxString cur_dir; + wxString description; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/src/spek-window.hh b/src/spek-window.hh @@ -1,51 +0,0 @@ -/* spek-window.hh - * - * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef SPEK_WINDOW_HH_ -#define SPEK_WINDOW_HH_ - -#include <wx/wx.h> - -class SpekSpectrogram; - -class SpekWindow : public wxFrame -{ -public: - SpekWindow(const wxString& path); - void open(const wxString& path); - -private: - void on_open(wxCommandEvent& event); - void on_save(wxCommandEvent& event); - void on_exit(wxCommandEvent& event); - void on_preferences(wxCommandEvent& event); - void on_help(wxCommandEvent& event); - void on_about(wxCommandEvent& event); - void on_notify(wxCommandEvent& event); - void on_visit(wxCommandEvent& event); - void on_close(wxCommandEvent& event); - - SpekSpectrogram *spectrogram; - wxString path; - wxString cur_dir; - wxString description; - - DECLARE_EVENT_TABLE() -}; - -#endif diff --git a/src/spek.cc b/src/spek.cc @@ -20,15 +20,13 @@ #include <wx/log.h> #include <wx/socket.h> -extern "C" { #include <spek-audio.h> -} -#include "spek-artwork.hh" -#include "spek-platform.hh" -#include "spek-preferences.hh" +#include "spek-artwork.h" +#include "spek-platform.h" +#include "spek-preferences.h" -#include "spek-window.hh" +#include "spek-window.h" class Spek: public wxApp { diff --git a/tests/test-utils.c b/tests/test-utils.c @@ -1,44 +0,0 @@ -/* test-utils.c - * - * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <spek-utils.h> - -#include "test.h" - -int main() -{ - ensure(0 == spek_vercmp("1.2.3", "1.2.3"), "1.2.3 == 1.2.3"); - ensure(1 == spek_vercmp("1.2.3", "1.2.2"), "1.2.3 > 1.2.2"); - ensure(-1 == spek_vercmp("1.2.2", "1.2.3"), "1.2.2 < 1.2.3"); - ensure(1 == spek_vercmp("1.2.3", "1"), "1.2.3 > 1"); - ensure(1 == spek_vercmp("1.2.3", "1."), "1.2.3 > 1."); - ensure(1 == spek_vercmp("1.2.3", "1.2"), "1.2.3 > 1.2"); - ensure(1 == spek_vercmp("1.2.3", "1.2."), "1.2.3 > 1.2."); - ensure(1 == spek_vercmp("1.15.3", "1.2"), "1.15.3 > 1.2"); - ensure(1 == spek_vercmp("2", "1.2.2"), "2 > 1.2.2"); - ensure(1 == spek_vercmp("1.2.3", ""), "1.2.3 > ''"); - ensure(0 == spek_vercmp("", ""), "'' == ''"); - ensure(0 == spek_vercmp("123", "123"), "123 == 123"); - ensure(-1 == spek_vercmp("0.2.3", "1"), "0.2.3 < 1"); - ensure(-1 == spek_vercmp("0.9.8", "0.10.1"), "0.9.8 < 0.10.1"); - ensure(-1 == spek_vercmp("1.200", "2.20"), "1.200 < 2.20"); - ensure(-1 == spek_vercmp("1.0.0", "2.0.0"), "1.0.0 < 2.0.0"); - ensure(-1 == spek_vercmp("1.0.0", "1.0.1"), "1.0.0 < 1.0.1"); - - return 0; -} diff --git a/tests/test-utils.cc b/tests/test-utils.cc @@ -0,0 +1,44 @@ +/* test-utils.cc + * + * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <spek-utils.h> + +#include "test.h" + +int main() +{ + ensure(0 == spek_vercmp("1.2.3", "1.2.3"), "1.2.3 == 1.2.3"); + ensure(1 == spek_vercmp("1.2.3", "1.2.2"), "1.2.3 > 1.2.2"); + ensure(-1 == spek_vercmp("1.2.2", "1.2.3"), "1.2.2 < 1.2.3"); + ensure(1 == spek_vercmp("1.2.3", "1"), "1.2.3 > 1"); + ensure(1 == spek_vercmp("1.2.3", "1."), "1.2.3 > 1."); + ensure(1 == spek_vercmp("1.2.3", "1.2"), "1.2.3 > 1.2"); + ensure(1 == spek_vercmp("1.2.3", "1.2."), "1.2.3 > 1.2."); + ensure(1 == spek_vercmp("1.15.3", "1.2"), "1.15.3 > 1.2"); + ensure(1 == spek_vercmp("2", "1.2.2"), "2 > 1.2.2"); + ensure(1 == spek_vercmp("1.2.3", ""), "1.2.3 > ''"); + ensure(0 == spek_vercmp("", ""), "'' == ''"); + ensure(0 == spek_vercmp("123", "123"), "123 == 123"); + ensure(-1 == spek_vercmp("0.2.3", "1"), "0.2.3 < 1"); + ensure(-1 == spek_vercmp("0.9.8", "0.10.1"), "0.9.8 < 0.10.1"); + ensure(-1 == spek_vercmp("1.200", "2.20"), "1.200 < 2.20"); + ensure(-1 == spek_vercmp("1.0.0", "2.0.0"), "1.0.0 < 2.0.0"); + ensure(-1 == spek_vercmp("1.0.0", "1.0.1"), "1.0.0 < 1.0.1"); + + return 0; +} diff --git a/tests/test.c b/tests/test.c @@ -1,26 +0,0 @@ -/* test.c - * - * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> - * - * Spek is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Spek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Spek. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "test.h" - -int main() -{ - ensure(2 + 2 == 4, "Hello, tests!"); - - return 0; -} diff --git a/tests/test.cc b/tests/test.cc @@ -0,0 +1,26 @@ +/* test.cc + * + * Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com> + * + * Spek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Spek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Spek. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "test.h" + +int main() +{ + ensure(2 + 2 == 4, "Hello, tests!"); + + return 0; +}