Commit a5bd4d27 authored by Ayyi's avatar Ayyi
Browse files

Fix 'multiple definition' compilation error

parent 57c57002
......@@ -48,11 +48,11 @@ playback audio samples triggered via Alsa Midi and Dbus.
alsa, ffmpeg, libsndfile. A list of packages for these dependencies can be
found for some distributions in the Docker files in the test directory.
- ``./autogen.sh && ./configure && make``
- ``./autogen.sh && ./configure && make``
If installing from a tarball you can omit the autogen step.
- To use the auditioner without installing, you can either launch the service
manually or copy auditioner.service to /usr/share/dbus-1/services/
manually or copy `auditioner.service` to `/usr/share/dbus-1/services/`
## Limitations
......
......@@ -11,20 +11,6 @@
int _debug_ = 0;
void
debug_printf(const char* func, int level, const char* format, ...)
{
va_list args;
va_start(args, format);
if (level <= _debug_) {
fprintf(stderr, "%s(): ", func);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
}
va_end(args);
}
void
warnprintf(char* format, ...)
{
......
......@@ -6,7 +6,6 @@
#define dbg(A, B, ...) debug_printf(__func__, A, B, ##__VA_ARGS__)
#define gerr(A, ...) g_critical("%s(): "A, __func__, ##__VA_ARGS__)
#define perr(A, ...) errprintf2(__func__, A, ##__VA_ARGS__)
#define gwarn(A, ...) g_warning("%s(): "A, __func__, ##__VA_ARGS__);
#define pwarn(A, ...) warnprintf2(__func__, A, ##__VA_ARGS__)
#define PF0 {printf("%s()...\n", __func__);}
#define PF {if(_debug_) printf("%s()...\n", __func__);}
......@@ -14,7 +13,7 @@
#define PF_DONE printf("%s(): done.\n", __func__);
#define P_GERR if(error){ gerr("%s\n", error->message); g_error_free(error); error = NULL; }
#define GERR_INFO if(error){ printf("%s\n", error->message); g_error_free(error); error = NULL; }
#define GERR_WARN if(error){ gwarn("%s", error->message); g_error_free(error); error = NULL; }
#define GERR_WARN if(error){ pwarn("%s", error->message); g_error_free(error); error = NULL; }
void debug_printf (const char* func, int level, const char* format, ...);
void warnprintf (char* format, ...);
......
......@@ -5,6 +5,6 @@ extern int wf_debug;
#define PF0 printf("%s\n", __func__)
#define dbg(A, STR, ...) ({if(A <= wf_debug) printf(STR"\n", ##__VA_ARGS__);})
#define perr(A, ...) {}
#define gwarn(A, ...) {}
#define pwarn(A, ...) {}
#endif
......@@ -22,6 +22,8 @@
#include "decoder/debug.h"
#include "decoder/ad.h"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
extern void int16_to_float(float* out, int16_t* in, int n_channels, int n_frames, int out_offset);
#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
......@@ -237,7 +239,7 @@ ad_open_ffmpeg(WfDecoder* decoder, const char* filename)
f->read_planar = ff_read_short_planar_to_planar;
break;
case AV_SAMPLE_FMT_FLT:
gwarn("no implementation of FLT to FLT");
pwarn("no implementation of FLT to FLT");
f->read_planar = ff_read_float_interleaved_to_planar;
break;
case AV_SAMPLE_FMT_FLTP:
......@@ -245,18 +247,18 @@ ad_open_ffmpeg(WfDecoder* decoder, const char* filename)
f->read_planar = ff_read_float_planar_to_planar;
break;
case AV_SAMPLE_FMT_S32:
gwarn("no implementation of S32 to FLT");
pwarn("no implementation of S32 to FLT");
f->read_planar = ff_read_int32_interleaved_to_planar;
break;
case AV_SAMPLE_FMT_S32P:
gwarn("planar (non-interleaved) unhandled!");
pwarn("planar (non-interleaved) unhandled!");
f->read = NULL;
break;
case AV_SAMPLE_FMT_U8:
f->read_planar = ff_read_u8_interleaved_to_planar;
break;
default:
gwarn("sample format not handled: %i", f->codec_context->sample_fmt);
pwarn("sample format not handled: %i", f->codec_context->sample_fmt);
break;
}
......@@ -398,7 +400,7 @@ ff_read_default_interleaved(WfDecoder* d, float* out, size_t len)
const int diff = f->output_clock - f->decoder_clock;
if (diff < 0) {
/* seek ended up past the wanted sample */
gwarn("audio seek failed.");
pwarn("audio seek failed.");
return -1;
} else if (f->tmp_buf.len < (diff * d->info.channels)) {
/* wanted sample not in current buffer - keep going */
......@@ -461,7 +463,7 @@ ff_read_short_interleaved_to_planar(WfDecoder* d, WfBuf16* buf)
f->frame_iter = 0;
if(avcodec_decode_audio4(f->codec_context, &f->frame, &got_frame, &f->packet) < 0){
gwarn("error decoding audio");
pwarn("error decoding audio");
}
}
......@@ -780,7 +782,7 @@ ff_read_float_planar_to_planar(WfDecoder* d, WfBuf16* buf)
f->frame_iter = 0;
if(avcodec_decode_audio4(f->codec_context, &f->frame, &got_frame, &f->packet) < 0){
gwarn("error decoding audio");
pwarn("error decoding audio");
}
}
if(got_frame){
......@@ -918,7 +920,7 @@ ff_read_int32_interleaved_to_planar(WfDecoder* d, WfBuf16* buf)
f->frame_iter = 0;
if(avcodec_decode_audio4(f->codec_context, &f->frame, &got_frame, &f->packet) < 0){
gwarn("error decoding audio");
pwarn("error decoding audio");
}
}
......@@ -983,7 +985,7 @@ ff_read_u8_interleaved_to_planar(WfDecoder* d, WfBuf16* buf)
f->frame_iter = 0;
if(avcodec_decode_audio4(f->codec_context, &f->frame, &got_frame, &f->packet) < 0){
gwarn("error decoding audio");
pwarn("error decoding audio");
}
}
......
/**
* +----------------------------------------------------------------------+
* | This file is part of the Ayyi project. http://ayyi.org |
* | copyright (C) 2011-2018 Tim Orford <tim@orford.org> |
* | copyright (C) 2011 Robin Gareus <robin@gareus.org> |
* +----------------------------------------------------------------------+
* | This program is free software; you can redistribute it and/or modify |
* | it under the terms of the GNU General Public License version 3 |
* | as published by the Free Software Foundation. |
* +----------------------------------------------------------------------+
*
*/
/*
+----------------------------------------------------------------------+
| This file is part of the Ayyi project. http://ayyi.org |
| copyright (C) 2011-2021 Tim Orford <tim@orford.org> |
| copyright (C) 2011 Robin Gareus <robin@gareus.org> |
+----------------------------------------------------------------------+
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 3 |
| as published by the Free Software Foundation. |
+----------------------------------------------------------------------+
|
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <math.h>
#include <sndfile.h>
#include <glib.h>
#include "decoder/debug.h"
#include "decoder/ad.h"
extern void int16_to_float(float* out, int16_t* in, int n_channels, int n_frames, int out_offset);
extern void int16_to_float (float* out, int16_t* in, int n_channels, int n_frames, int out_offset);
typedef struct {
SF_INFO sfinfo;
......@@ -41,7 +36,7 @@ struct _WfBuf16 // also defined in waveform.h
int
parse_bit_depth(int format)
parse_bit_depth (int format)
{
/* see http://www.mega-nerd.com/libsndfile/api.html */
switch (format&0x0f) {
......@@ -59,7 +54,7 @@ parse_bit_depth(int format)
int
ad_info_sndfile(WfDecoder* d)
ad_info_sndfile (WfDecoder* d)
{
SndfileDecoder* sf = d->d;
if (!sf) return -1;
......@@ -79,7 +74,7 @@ ad_info_sndfile(WfDecoder* d)
static gboolean
ad_open_sndfile(WfDecoder* decoder, const char* filename)
ad_open_sndfile (WfDecoder* decoder, const char* filename)
{
SndfileDecoder* priv = decoder->d = g_new0(SndfileDecoder, 1);
priv->sfinfo.format = 0;
......@@ -94,7 +89,7 @@ ad_open_sndfile(WfDecoder* decoder, const char* filename)
int
ad_close_sndfile(WfDecoder* decoder)
ad_close_sndfile (WfDecoder* decoder)
{
SndfileDecoder* priv = (SndfileDecoder*)decoder->d;
if (!priv) return -1;
......@@ -107,7 +102,7 @@ ad_close_sndfile(WfDecoder* decoder)
int64_t
ad_seek_sndfile(WfDecoder* d, int64_t pos)
ad_seek_sndfile (WfDecoder* d, int64_t pos)
{
SndfileDecoder* priv = (SndfileDecoder*)d->d;
if (!priv) return -1;
......@@ -116,7 +111,7 @@ ad_seek_sndfile(WfDecoder* d, int64_t pos)
ssize_t
ad_read_sndfile(WfDecoder* d, float* out, size_t len)
ad_read_sndfile (WfDecoder* d, float* out, size_t len)
{
SndfileDecoder* priv = (SndfileDecoder*)d->d;
if (!priv) return -1;
......@@ -133,7 +128,7 @@ ad_read_sndfile(WfDecoder* d, float* out, size_t len)
}
#ifdef DEBUG
default:
gwarn("unhandled bit depth: %i", d->info.bit_depth);
pwarn("unhandled bit depth: %i", d->info.bit_depth);
#endif
}
......@@ -142,7 +137,7 @@ ad_read_sndfile(WfDecoder* d, float* out, size_t len)
ssize_t
ad_read_sndfile_short(WfDecoder* d, WfBuf16* buf)
ad_read_sndfile_short (WfDecoder* d, WfBuf16* buf)
{
SndfileDecoder* sf = (SndfileDecoder*)d->d;
......@@ -195,7 +190,7 @@ ad_read_sndfile_short(WfDecoder* d, WfBuf16* buf)
int
ad_eval_sndfile(const char *f)
ad_eval_sndfile (const char *f)
{
char *ext = strrchr(f, '.');
if (!ext) return 5;
......@@ -247,7 +242,7 @@ const static AdPlugin ad_sndfile = {
/* dlopen handler */
const AdPlugin*
get_sndfile()
get_sndfile ()
{
return &ad_sndfile;
}
......
/*
Example command line program to demonstrate usage of the Ayyi Auditioner
service.
+----------------------------------------------------------------------+
| This file is part of the Ayyi project. http://www.ayyi.org |
| copyright (C) 2004-2021 Tim Orford <tim@orford.org> |
+----------------------------------------------------------------------+
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 3 |
| as published by the Free Software Foundation. |
+----------------------------------------------------------------------+
|
| audition.c
|
| Example command line program to demonstrate usage of the
| Ayyi Auditioner service.
|
*/
--------------------------------------------------------------------
This file is part of the Ayyi project. http://ayyi.org
copyright (C) 2011-2015 Tim Orford <tim@orford.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3
as published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <libgen.h>
#include <getopt.h>
#include <math.h>
#include <sys/time.h>
#include <glib.h>
#include <dbus/dbus-glib-bindings.h>
#ifdef USE_SYSLOG
......
/**
* +----------------------------------------------------------------------+
* | This file is part of the Ayyi project. http://www.ayyi.org |
* | copyright (C) 2011-2018 Tim Orford <tim@orford.org> |
* +----------------------------------------------------------------------+
* | This program is free software; you can redistribute it and/or modify |
* | it under the terms of the GNU General Public License version 3 |
* | as published by the Free Software Foundation. |
* +----------------------------------------------------------------------+
*
*/
/*
In the sampler plugin, when a new NOTE_ON arrives, the following occurs:
1. run() trys mutex and checks for new midi events
2. if pending program change, or no sample loaded, push event to deferred queue.
3. when program change is finished, the alsa event is put into ons/offs/velocities.
Playback has to wait for 2 things:
1. pending program change
2. mutex free - locked by worker thread when doing sampleload.
*/
/*
based on jack-dssi-host.c
Copyright 2004, 2009 Chris Cannam, Steve Harris and Sean Bolton.
Permission to use, copy, modify, distribute, and sell this software
for any purpose is hereby granted without fee, provided that the
above copyright notice and this permission notice are included in
all copies or substantial portions of the software.
*/
+----------------------------------------------------------------------+
| This file is part of the Ayyi project. http://www.ayyi.org |
| copyright (C) 2011-2021 Tim Orford <tim@orford.org> |
+----------------------------------------------------------------------+
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 3 |
| as published by the Free Software Foundation. |
+----------------------------------------------------------------------+
|
| auditioner.c
|
| In the sampler plugin, when a new NOTE_ON arrives, the following occurs:
|
| 1. run() trys mutex and checks for new midi events
| 2. if pending program change, or no sample loaded, push event to deferred queue.
| 3. when program change is finished, the alsa event is put into ons/offs/velocities.
|
| Playback has to wait for 2 things:
|
| 1. pending program change
| 2. mutex free - locked by worker thread when doing sample-load.
|
+----------------------------------------------------------------------
|
| based on jack-dssi-host.c
|
| Copyright 2004, 2009 Chris Cannam, Steve Harris and Sean Bolton.
|
| Permission to use, copy, modify, distribute, and sell this software
| for any purpose is hereby granted without fee, provided that the
| above copyright notice and this permission notice are included in
| all copies or substantial portions of the software.
|
*/
#define _DEFAULT_SOURCE 1
#define _SVID_SOURCE 1
#define _ISOC99_SOURCE 1
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <assert.h>
#include <dlfcn.h>
#include <unistd.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <signal.h>
#include <dirent.h>
#include <time.h>
#include <glib.h>
#include <ladspa.h>
#include "plugin/api/dssi.h"
......@@ -127,11 +117,6 @@ static d3h_instance_t** pluginControlInInstances; /* maps global cont
static unsigned long* pluginControlInPortNumbers; /* maps global control in # to instance LADSPA port # */
static int* pluginPortUpdated; /* indexed by global control in # */
#ifdef USE_OSC
static char osc_path_tmp[1024];
lo_server_thread serverThread;
#endif
static char* projectDirectory;
static sigset_t _signals;
......@@ -148,11 +133,17 @@ static int midiEventReadIndex = 0, midiEventWriteIndex = 0;
static pthread_mutex_t midiEventBufferMutex = PTHREAD_MUTEX_INITIALIZER;
LADSPA_Data get_port_default(const LADSPA_Descriptor* plugin, int port);
static void start_dbus ();
LADSPA_Data get_port_default (const LADSPA_Descriptor* plugin, int port);
void osc_error (int num, const char* m, const char* path);
int osc_message_handler (const char* path, const char* types, lo_arg**, int argc, void* data, void* user_data);
int osc_debug_handler (const char* path, const char* types, lo_arg**, int argc, void* data, void* user_data);
#ifdef USE_OSC
static char osc_path_tmp[1024];
lo_server_thread serverThread;
static void osc_error (int num, const char* m, const char* path);
extern int osc_message_handler (const char* path, const char* types, lo_arg**, int argc, void* data, void* user_data);
extern int osc_debug_handler (const char* path, const char* types, lo_arg**, int argc, void* data, void* user_data);
#endif
int
......@@ -178,7 +169,7 @@ request_non_rt_thread (LADSPA_Handle instance, void (*RunFunction)(LADSPA_Handle
}
gboolean next(gpointer user_data)
gboolean next (gpointer user_data)
{
dbg(0, "queue len: %i", g_list_length(play_queue));
......@@ -1230,58 +1221,7 @@ main (int argc, char** argv)
}
}
#ifdef DBUS_HAS_OWN_THREAD
msg_queue = g_async_queue_new();
gpointer dbus_thread(gpointer data)
{
dbg(0, "...");
GMainContext* context = g_main_context_new();
/* Start Dbus server */
AuditionerDbus* bus = auditioner_dbus_get_instance();
if (!auditioner_dbus_register_service (bus, context)) {
dbg(0, "dbus registration failed!");
exit(EXIT_FAILURE);
}
g_async_queue_ref(msg_queue);
gboolean worker_timeout(gpointer data)
{
//check for new work
while(g_async_queue_length(msg_queue)){
char* message = g_async_queue_pop(msg_queue); // blocks
dbg(0, "new message! '%s'", message);
play_note(message, NULL);
}
return G_SOURCE_CONTINUE;
}
GSource* source = g_timeout_source_new(500);
gpointer _data = NULL;
g_source_set_callback(source, worker_timeout, _data, NULL);
g_source_attach(source, context);
g_main_loop_run (g_main_loop_new (context, 0));
return NULL;
}
// TODO its probably a bad idea to have the dbus code in a separate thread.
GError* error = NULL;
if(!g_thread_create(dbus_thread, NULL, FALSE, &error)){
perr("error creating thread: %s\n", error->message);
g_error_free(error);
}
#else
AuditionerDbus* bus = auditioner_dbus_get_instance();
if (!auditioner_dbus_register_service (bus, NULL)) {
dbg(0, "dbus registration failed!");
exit(EXIT_FAILURE);
}
#endif
start_dbus();
#ifdef USE_OSC
/* Create OSC thread */
......@@ -1600,6 +1540,62 @@ main (int argc, char** argv)
}
static void
start_dbus ()
{
#ifdef DBUS_HAS_OWN_THREAD
msg_queue = g_async_queue_new();
gpointer dbus_thread(gpointer data)
{
dbg(0, "...");
GMainContext* context = g_main_context_new();
/* Start Dbus server */
AuditionerDbus* bus = auditioner_dbus_get_instance();
if (!auditioner_dbus_register_service (bus, context)) {
dbg(0, "dbus registration failed!");
exit(EXIT_FAILURE);
}
g_async_queue_ref(msg_queue);
gboolean worker_timeout(gpointer data)
{
//check for new work
while(g_async_queue_length(msg_queue)){
char* message = g_async_queue_pop(msg_queue); // blocks
dbg(0, "new message! '%s'", message);
play_note(message, NULL);
}
return G_SOURCE_CONTINUE;
}
GSource* source = g_timeout_source_new(500);
gpointer _data = NULL;
g_source_set_callback(source, worker_timeout, _data, NULL);
g_source_attach(source, context);
g_main_loop_run (g_main_loop_new (context, 0));
return NULL;
}
// TODO its probably a bad idea to have the dbus code in a separate thread.
GError* error = NULL;
if(!g_thread_create(dbus_thread, NULL, FALSE, &error)){
perr("error creating thread: %s\n", error->message);
g_error_free(error);
}
#else
AuditionerDbus* bus = auditioner_dbus_get_instance();
if (!auditioner_dbus_register_service (bus, NULL)) {
dbg(0, "dbus registration failed!");
exit(EXIT_FAILURE);
}
#endif
}
LADSPA_Data
get_port_default (const LADSPA_Descriptor *plugin, int port)
{
......@@ -1673,16 +1669,16 @@ get_port_default (const LADSPA_Descriptor *plugin, int port)
}
void
#ifdef USE_OSC
static void
osc_error (int num, const char *msg, const char *path)
{
dbg(0, "%s: liblo server error %d in path %s: %s", myName, num, path, msg);
}
#ifdef USE_OSC
#include "osc.c"
#endif //USE_OSC
#endif
static int
......@@ -1855,7 +1851,7 @@ next_note ()
char*
get_status(int* queue_size)
get_status (int* queue_size)
{
if(playing){
*queue_size = g_list_length(play_queue);
......
/*
This file is part of the Ayyi project. http://ayyi.org
copyright (C) 2010-2018 Tim Orford <tim@orford.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3
as published by the Free Software Foundation.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+----------------------------------------------------------------------+
| This file is part of the Ayyi project. http://www.ayyi.org |
| copyright (C) 2004-2021 Tim Orford <tim@orford.org> |
+----------------------------------------------------------------------+
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 3 |
| as published by the Free Software Foundation. |
+----------------------------------------------------------------------+
|