| @@ -0,0 +1,215 @@ | |||
| /* | |||
| * Carla Native Plugin API (JACK Compatibility header) | |||
| * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program 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 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * 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. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #ifndef CARLA_NATIVE_JACK_H_INCLUDED | |||
| #define CARLA_NATIVE_JACK_H_INCLUDED | |||
| #include "CarlaNative.h" | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Macros */ | |||
| #define JACK_DEFAULT_AUDIO_TYPE "audio" | |||
| #define JACK_DEFAULT_MIDI_TYPE "midi" | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Basic types */ | |||
| typedef float jack_default_audio_sample_t; | |||
| typedef uint32_t jack_nframes_t; | |||
| typedef void (*jack_shutdown_callback)(void* ptr); | |||
| typedef int (*jack_process_callback)(jack_nframes_t nframes, void* ptr); | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Enums */ | |||
| typedef enum { | |||
| JackPortIsInput = 1 << 0, | |||
| JackPortIsOutput = 1 << 1 | |||
| } jack___t; | |||
| typedef enum { | |||
| JackNoStartServer = 0, | |||
| JackServerName | |||
| } jack_options_t; | |||
| typedef enum { | |||
| JackNoError = 0x0 | |||
| } jack_status_t; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Structs */ | |||
| typedef struct { | |||
| bool isInput; | |||
| void* buffer; | |||
| } jack_port_t; | |||
| typedef struct { | |||
| // current state | |||
| bool active; | |||
| const char* clientName; | |||
| jack_nframes_t bufferSize; | |||
| jack_nframes_t sampleRate; | |||
| // callbacks | |||
| jack_process_callback processCallback; | |||
| void* processPtr; | |||
| // ports | |||
| jack_port_t* portsAudioIn[8]; | |||
| jack_port_t* portsAudioOut[8]; | |||
| } jack_client_t; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Client functions, defined in the plugin code */ | |||
| jack_client_t* jack_client_open(const char* clientname, jack_options_t options, jack_status_t* status, ...); | |||
| int jack_client_close(jack_client_t* client); | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Callback functions */ | |||
| static inline | |||
| int jack_on_shutdown(jack_client_t* client, jack_shutdown_callback callback, void* ptr) | |||
| { | |||
| return 0; | |||
| // unused | |||
| (void)client; | |||
| (void)callback; | |||
| (void)ptr; | |||
| } | |||
| static inline | |||
| int jack_set_process_callback(jack_client_t* client, jack_process_callback callback, void* ptr) | |||
| { | |||
| client->processCallback = callback; | |||
| client->processPtr = ptr; | |||
| return 0; | |||
| } | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Port functions */ | |||
| static inline | |||
| jack_port_t* jack_port_register(jack_client_t* client, const char* name, const char* type, jack___t hints, jack_nframes_t buffersize) | |||
| { | |||
| jack_port_t** const ports = (hints & JackPortIsInput) ? client->portsAudioIn : client->portsAudioOut; | |||
| for (int i=0; i<8; ++i) | |||
| { | |||
| if (ports[i] != NULL) | |||
| continue; | |||
| jack_port_t* const port = (jack_port_t*)calloc(1, sizeof(jack_port_t)); | |||
| if (port == NULL) | |||
| return NULL; | |||
| port->isInput = (hints & JackPortIsInput); | |||
| ports[i] = port; | |||
| return port; | |||
| } | |||
| return NULL; | |||
| // unused | |||
| (void)name; | |||
| (void)type; | |||
| (void)buffersize; | |||
| } | |||
| static inline | |||
| int jack_port_unregister(jack_client_t* client, jack_port_t* port) | |||
| { | |||
| jack_port_t** const ports = port->isInput ? client->portsAudioIn : client->portsAudioOut; | |||
| for (int i=0; i<8; ++i) | |||
| { | |||
| if (ports[i] == port) | |||
| { | |||
| ports[i] = nullptr; | |||
| return 0; | |||
| } | |||
| } | |||
| return 1; | |||
| } | |||
| static inline | |||
| void* jack_port_get_buffer(const jack_port_t* port, jack_nframes_t nframes) | |||
| { | |||
| return port->buffer; | |||
| // unused | |||
| (void)nframes; | |||
| } | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * [De/]Activate */ | |||
| static inline | |||
| int jack_activate(jack_client_t* client) | |||
| { | |||
| client->active = true; | |||
| return 0; | |||
| } | |||
| static inline | |||
| int jack_deactivate(jack_client_t* client) | |||
| { | |||
| client->active = false; | |||
| return 0; | |||
| } | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Get data functions */ | |||
| static inline | |||
| const char* jack_get_client_name(const jack_client_t* client) | |||
| { | |||
| return client->clientName; | |||
| } | |||
| static inline | |||
| jack_nframes_t jack_get_buffer_size(const jack_client_t* client) | |||
| { | |||
| return client->bufferSize; | |||
| } | |||
| static inline | |||
| jack_nframes_t jack_get_sample_rate(const jack_client_t* client) | |||
| { | |||
| return client->sampleRate; | |||
| } | |||
| /* ------------------------------------------------------------------------------------------------------------ */ | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif /* CARLA_NATIVE_JACK_H_INCLUDED */ | |||
| @@ -0,0 +1,369 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program 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 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * 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. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaNative.hpp" | |||
| #include "CarlaMutex.hpp" | |||
| #include "CarlaJuceUtils.hpp" | |||
| #include "juce_audio_basics.h" | |||
| #include "zita-jaaa/source/audio.cc" | |||
| #include "zita-jaaa/source/rngen.cc" | |||
| #include "zita-jaaa/source/spectwin.cc" | |||
| #include "zita-jaaa/source/styles.cc" | |||
| using juce::FloatVectorOperations; | |||
| using juce::ScopedPointer; | |||
| // ----------------------------------------------------------------------- | |||
| // fake jack_client_open/close per plugin | |||
| static jack_client_t* gLastJackClient = nullptr; | |||
| jack_client_t* jack_client_open(const char*, jack_options_t, jack_status_t* status, ...) | |||
| { | |||
| if (status != NULL) | |||
| *status = JackNoError; | |||
| return gLastJackClient; | |||
| } | |||
| int jack_client_close(jack_client_t* client) | |||
| { | |||
| carla_zeroStruct(client, 1); | |||
| return 0; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // Jaaa Plugin | |||
| class JaaaPlugin : public NativePluginClass | |||
| { | |||
| public: | |||
| enum Parameters { | |||
| kParameterInput = 0, | |||
| kParameterCount | |||
| }; | |||
| JaaaPlugin(const NativeHostDescriptor* const host) | |||
| : NativePluginClass(host), | |||
| fJackClient(), | |||
| fMutex(), | |||
| xrm(), | |||
| itcc(nullptr), | |||
| driver(nullptr), | |||
| display(nullptr), | |||
| rootwin(nullptr), | |||
| mainwin(nullptr), | |||
| xhandler(nullptr), | |||
| leakDetector_JaaaPlugin() | |||
| { | |||
| CARLA_SAFE_ASSERT(host != nullptr); | |||
| int argc = 1; | |||
| char* argv[] = { (char*)"jaaa" }; | |||
| xrm.init(&argc, argv, (char*)"jaaa", nullptr, 0); | |||
| fParameters[kParameterInput] = 1.0f; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin parameter calls | |||
| uint32_t getParameterCount() const override | |||
| { | |||
| return kParameterCount; | |||
| } | |||
| const NativeParameter* getParameterInfo(const uint32_t index) const override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < kParameterCount, nullptr); | |||
| static NativeParameter param; | |||
| int hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE; | |||
| // reset | |||
| param.name = nullptr; | |||
| param.unit = nullptr; | |||
| param.ranges.def = 0.0f; | |||
| param.ranges.min = 0.0f; | |||
| param.ranges.max = 1.0f; | |||
| param.ranges.step = 1.0f; | |||
| param.ranges.stepSmall = 1.0f; | |||
| param.ranges.stepLarge = 1.0f; | |||
| param.scalePointCount = 0; | |||
| param.scalePoints = nullptr; | |||
| switch (index) | |||
| { | |||
| case kParameterInput: | |||
| hints |= NATIVE_PARAMETER_IS_INTEGER; | |||
| param.name = "Input"; | |||
| param.ranges.def = 1.0f; | |||
| param.ranges.min = 1.0f; | |||
| param.ranges.max = 8.0f; | |||
| break; | |||
| } | |||
| param.hints = static_cast<NativeParameterHints>(hints); | |||
| return ¶m; | |||
| } | |||
| float getParameterValue(const uint32_t index) const override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < kParameterCount, 0.0f); | |||
| return fParameters[index]; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin state calls | |||
| void setParameterValue(const uint32_t index, const float value) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < kParameterCount,); | |||
| fParameters[index] = value; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin process calls | |||
| void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override | |||
| { | |||
| const CarlaMutexTryLocker cmtl(fMutex); | |||
| if (itcc == nullptr || ! fJackClient.active || ! cmtl.wasLocked()) | |||
| { | |||
| const int iframes(static_cast<int>(frames)); | |||
| for (int i=0; i<8; ++i) | |||
| FloatVectorOperations::clear(outBuffer[i], iframes); | |||
| return; | |||
| } | |||
| for (int i=0; i<8; ++i) | |||
| fJackClient.portsAudioIn[i]->buffer = inBuffer[i]; | |||
| for (int i=0; i<8; ++i) | |||
| fJackClient.portsAudioOut[i]->buffer = outBuffer[i]; | |||
| fJackClient.processCallback(frames, fJackClient.processPtr); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin UI calls | |||
| void uiShow(const bool show) override | |||
| { | |||
| const CarlaMutexLocker cml(fMutex); | |||
| if (show) | |||
| { | |||
| if (itcc == nullptr) | |||
| { | |||
| carla_zeroStruct(fJackClient); | |||
| gLastJackClient = &fJackClient; | |||
| fJackClient.clientName = getUiName(); | |||
| fJackClient.bufferSize = getBufferSize(); | |||
| fJackClient.sampleRate = getSampleRate(); | |||
| itcc = new ITC_ctrl(); | |||
| driver = new Audio(itcc, getUiName()); | |||
| driver->init_jack(nullptr); | |||
| display = new X_display(nullptr); | |||
| if (display->dpy() == nullptr) | |||
| { | |||
| driver = nullptr; | |||
| itcc = nullptr; | |||
| return hostUiUnavailable(); | |||
| } | |||
| init_styles(display, &xrm); | |||
| rootwin = new X_rootwin(display); | |||
| mainwin = new Spectwin(rootwin, &xrm, driver); | |||
| xhandler = new X_handler(display, itcc, EV_X11); | |||
| if (const uintptr_t winId = getUiParentId()) | |||
| XSetTransientForHint(display->dpy(), mainwin->win(), static_cast<Window>(winId)); | |||
| } | |||
| xhandler->next_event(); | |||
| XFlush(display->dpy()); | |||
| } | |||
| else | |||
| { | |||
| xhandler = nullptr; | |||
| mainwin = nullptr; | |||
| rootwin = nullptr; | |||
| display = nullptr; | |||
| driver = nullptr; | |||
| itcc = nullptr; | |||
| carla_zeroStruct(fJackClient); | |||
| } | |||
| } | |||
| void uiIdle() override | |||
| { | |||
| if (itcc == nullptr) | |||
| return; | |||
| //for (int i=3; --i>=0;) | |||
| { | |||
| switch (itcc->get_event()) | |||
| { | |||
| case EV_TRIG: | |||
| mainwin->handle_trig(); | |||
| rootwin->handle_event(); | |||
| XFlush(display->dpy()); | |||
| break; | |||
| case EV_MESG: | |||
| mainwin->handle_mesg(itcc->get_message()); | |||
| rootwin->handle_event(); | |||
| XFlush(display->dpy()); | |||
| break; | |||
| case EV_X11: | |||
| rootwin->handle_event(); | |||
| xhandler->next_event(); | |||
| break; | |||
| } | |||
| } | |||
| // check if parameters were updated | |||
| if (mainwin->_input+1 != static_cast<int>(fParameters[kParameterInput])) | |||
| { | |||
| fParameters[kParameterInput] = mainwin->_input+1; | |||
| uiParameterChanged(kParameterInput, fParameters[kParameterInput]); | |||
| } | |||
| // check if UI was closed | |||
| if (! mainwin->running()) | |||
| { | |||
| { | |||
| const CarlaMutexLocker cml(fMutex); | |||
| xhandler = nullptr; | |||
| mainwin = nullptr; | |||
| rootwin = nullptr; | |||
| display = nullptr; | |||
| driver = nullptr; | |||
| itcc = nullptr; | |||
| carla_zeroStruct(fJackClient); | |||
| } | |||
| uiClosed(); | |||
| return; | |||
| } | |||
| } | |||
| void uiSetParameterValue(const uint32_t index, const float value) override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < kParameterCount,); | |||
| const CarlaMutexLocker cml(fMutex); | |||
| if (itcc == nullptr) | |||
| return; | |||
| switch (index) | |||
| { | |||
| case kParameterInput: | |||
| mainwin->set_input(static_cast<int>(value)-1); | |||
| break; | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin dispatcher calls | |||
| void bufferSizeChanged(const uint32_t bufferSize) override | |||
| { | |||
| fJackClient.bufferSize = bufferSize; | |||
| } | |||
| void sampleRateChanged(const double sampleRate) override | |||
| { | |||
| fJackClient.sampleRate = sampleRate; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| // Fake jack client | |||
| jack_client_t fJackClient; | |||
| // Mutex just in case | |||
| CarlaMutex fMutex; | |||
| // Zita stuff (core) | |||
| X_resman xrm; | |||
| ScopedPointer<ITC_ctrl> itcc; | |||
| ScopedPointer<Audio> driver; | |||
| ScopedPointer<X_display> display; | |||
| ScopedPointer<X_rootwin> rootwin; | |||
| ScopedPointer<Spectwin> mainwin; | |||
| ScopedPointer<X_handler> xhandler; | |||
| float fParameters[kParameterCount]; | |||
| PluginClassEND(JaaaPlugin) | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JaaaPlugin) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| static const NativePluginDescriptor jaaaDesc = { | |||
| /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | |||
| /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE | |||
| |NATIVE_PLUGIN_HAS_UI | |||
| |NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS | |||
| |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD | |||
| |NATIVE_PLUGIN_USES_PARENT_ID), | |||
| /* supports */ static_cast<NativePluginSupports>(0x0), | |||
| /* audioIns */ 8, | |||
| /* audioOuts */ 8, | |||
| /* midiIns */ 0, | |||
| /* midiOuts */ 0, | |||
| /* paramIns */ JaaaPlugin::kParameterCount, | |||
| /* paramOuts */ 0, | |||
| /* name */ "Jaaa", | |||
| /* label */ "jaaa", | |||
| /* maker */ "Fons Adriaensen", | |||
| /* copyright */ "GPL v2+", | |||
| PluginDescriptorFILL(JaaaPlugin) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zita_jaaa(); | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zita_jaaa() | |||
| { | |||
| carla_register_native_plugin(&jaaaDesc); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -0,0 +1 @@ | |||
| Fons Adriaensen <fons@linuxaudio.org> | |||
| @@ -0,0 +1,340 @@ | |||
| GNU GENERAL PUBLIC LICENSE | |||
| Version 2, June 1991 | |||
| Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |||
| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
| Everyone is permitted to copy and distribute verbatim copies | |||
| of this license document, but changing it is not allowed. | |||
| Preamble | |||
| The licenses for most software are designed to take away your | |||
| freedom to share and change it. By contrast, the GNU General Public | |||
| License is intended to guarantee your freedom to share and change free | |||
| software--to make sure the software is free for all its users. This | |||
| General Public License applies to most of the Free Software | |||
| Foundation's software and to any other program whose authors commit to | |||
| using it. (Some other Free Software Foundation software is covered by | |||
| the GNU Library General Public License instead.) You can apply it to | |||
| your programs, too. | |||
| When we speak of free software, we are referring to freedom, not | |||
| price. Our General Public Licenses are designed to make sure that you | |||
| have the freedom to distribute copies of free software (and charge for | |||
| this service if you wish), that you receive source code or can get it | |||
| if you want it, that you can change the software or use pieces of it | |||
| in new free programs; and that you know you can do these things. | |||
| To protect your rights, we need to make restrictions that forbid | |||
| anyone to deny you these rights or to ask you to surrender the rights. | |||
| These restrictions translate to certain responsibilities for you if you | |||
| distribute copies of the software, or if you modify it. | |||
| For example, if you distribute copies of such a program, whether | |||
| gratis or for a fee, you must give the recipients all the rights that | |||
| you have. You must make sure that they, too, receive or can get the | |||
| source code. And you must show them these terms so they know their | |||
| rights. | |||
| We protect your rights with two steps: (1) copyright the software, and | |||
| (2) offer you this license which gives you legal permission to copy, | |||
| distribute and/or modify the software. | |||
| Also, for each author's protection and ours, we want to make certain | |||
| that everyone understands that there is no warranty for this free | |||
| software. If the software is modified by someone else and passed on, we | |||
| want its recipients to know that what they have is not the original, so | |||
| that any problems introduced by others will not reflect on the original | |||
| authors' reputations. | |||
| Finally, any free program is threatened constantly by software | |||
| patents. We wish to avoid the danger that redistributors of a free | |||
| program will individually obtain patent licenses, in effect making the | |||
| program proprietary. To prevent this, we have made it clear that any | |||
| patent must be licensed for everyone's free use or not licensed at all. | |||
| The precise terms and conditions for copying, distribution and | |||
| modification follow. | |||
| GNU GENERAL PUBLIC LICENSE | |||
| TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
| 0. This License applies to any program or other work which contains | |||
| a notice placed by the copyright holder saying it may be distributed | |||
| under the terms of this General Public License. The "Program", below, | |||
| refers to any such program or work, and a "work based on the Program" | |||
| means either the Program or any derivative work under copyright law: | |||
| that is to say, a work containing the Program or a portion of it, | |||
| either verbatim or with modifications and/or translated into another | |||
| language. (Hereinafter, translation is included without limitation in | |||
| the term "modification".) Each licensee is addressed as "you". | |||
| Activities other than copying, distribution and modification are not | |||
| covered by this License; they are outside its scope. The act of | |||
| running the Program is not restricted, and the output from the Program | |||
| is covered only if its contents constitute a work based on the | |||
| Program (independent of having been made by running the Program). | |||
| Whether that is true depends on what the Program does. | |||
| 1. You may copy and distribute verbatim copies of the Program's | |||
| source code as you receive it, in any medium, provided that you | |||
| conspicuously and appropriately publish on each copy an appropriate | |||
| copyright notice and disclaimer of warranty; keep intact all the | |||
| notices that refer to this License and to the absence of any warranty; | |||
| and give any other recipients of the Program a copy of this License | |||
| along with the Program. | |||
| You may charge a fee for the physical act of transferring a copy, and | |||
| you may at your option offer warranty protection in exchange for a fee. | |||
| 2. You may modify your copy or copies of the Program or any portion | |||
| of it, thus forming a work based on the Program, and copy and | |||
| distribute such modifications or work under the terms of Section 1 | |||
| above, provided that you also meet all of these conditions: | |||
| a) You must cause the modified files to carry prominent notices | |||
| stating that you changed the files and the date of any change. | |||
| b) You must cause any work that you distribute or publish, that in | |||
| whole or in part contains or is derived from the Program or any | |||
| part thereof, to be licensed as a whole at no charge to all third | |||
| parties under the terms of this License. | |||
| c) If the modified program normally reads commands interactively | |||
| when run, you must cause it, when started running for such | |||
| interactive use in the most ordinary way, to print or display an | |||
| announcement including an appropriate copyright notice and a | |||
| notice that there is no warranty (or else, saying that you provide | |||
| a warranty) and that users may redistribute the program under | |||
| these conditions, and telling the user how to view a copy of this | |||
| License. (Exception: if the Program itself is interactive but | |||
| does not normally print such an announcement, your work based on | |||
| the Program is not required to print an announcement.) | |||
| These requirements apply to the modified work as a whole. If | |||
| identifiable sections of that work are not derived from the Program, | |||
| and can be reasonably considered independent and separate works in | |||
| themselves, then this License, and its terms, do not apply to those | |||
| sections when you distribute them as separate works. But when you | |||
| distribute the same sections as part of a whole which is a work based | |||
| on the Program, the distribution of the whole must be on the terms of | |||
| this License, whose permissions for other licensees extend to the | |||
| entire whole, and thus to each and every part regardless of who wrote it. | |||
| Thus, it is not the intent of this section to claim rights or contest | |||
| your rights to work written entirely by you; rather, the intent is to | |||
| exercise the right to control the distribution of derivative or | |||
| collective works based on the Program. | |||
| In addition, mere aggregation of another work not based on the Program | |||
| with the Program (or with a work based on the Program) on a volume of | |||
| a storage or distribution medium does not bring the other work under | |||
| the scope of this License. | |||
| 3. You may copy and distribute the Program (or a work based on it, | |||
| under Section 2) in object code or executable form under the terms of | |||
| Sections 1 and 2 above provided that you also do one of the following: | |||
| a) Accompany it with the complete corresponding machine-readable | |||
| source code, which must be distributed under the terms of Sections | |||
| 1 and 2 above on a medium customarily used for software interchange; or, | |||
| b) Accompany it with a written offer, valid for at least three | |||
| years, to give any third party, for a charge no more than your | |||
| cost of physically performing source distribution, a complete | |||
| machine-readable copy of the corresponding source code, to be | |||
| distributed under the terms of Sections 1 and 2 above on a medium | |||
| customarily used for software interchange; or, | |||
| c) Accompany it with the information you received as to the offer | |||
| to distribute corresponding source code. (This alternative is | |||
| allowed only for noncommercial distribution and only if you | |||
| received the program in object code or executable form with such | |||
| an offer, in accord with Subsection b above.) | |||
| The source code for a work means the preferred form of the work for | |||
| making modifications to it. For an executable work, complete source | |||
| code means all the source code for all modules it contains, plus any | |||
| associated interface definition files, plus the scripts used to | |||
| control compilation and installation of the executable. However, as a | |||
| special exception, the source code distributed need not include | |||
| anything that is normally distributed (in either source or binary | |||
| form) with the major components (compiler, kernel, and so on) of the | |||
| operating system on which the executable runs, unless that component | |||
| itself accompanies the executable. | |||
| If distribution of executable or object code is made by offering | |||
| access to copy from a designated place, then offering equivalent | |||
| access to copy the source code from the same place counts as | |||
| distribution of the source code, even though third parties are not | |||
| compelled to copy the source along with the object code. | |||
| 4. You may not copy, modify, sublicense, or distribute the Program | |||
| except as expressly provided under this License. Any attempt | |||
| otherwise to copy, modify, sublicense or distribute the Program is | |||
| void, and will automatically terminate your rights under this License. | |||
| However, parties who have received copies, or rights, from you under | |||
| this License will not have their licenses terminated so long as such | |||
| parties remain in full compliance. | |||
| 5. You are not required to accept this License, since you have not | |||
| signed it. However, nothing else grants you permission to modify or | |||
| distribute the Program or its derivative works. These actions are | |||
| prohibited by law if you do not accept this License. Therefore, by | |||
| modifying or distributing the Program (or any work based on the | |||
| Program), you indicate your acceptance of this License to do so, and | |||
| all its terms and conditions for copying, distributing or modifying | |||
| the Program or works based on it. | |||
| 6. Each time you redistribute the Program (or any work based on the | |||
| Program), the recipient automatically receives a license from the | |||
| original licensor to copy, distribute or modify the Program subject to | |||
| these terms and conditions. You may not impose any further | |||
| restrictions on the recipients' exercise of the rights granted herein. | |||
| You are not responsible for enforcing compliance by third parties to | |||
| this License. | |||
| 7. If, as a consequence of a court judgment or allegation of patent | |||
| infringement or for any other reason (not limited to patent issues), | |||
| conditions are imposed on you (whether by court order, agreement or | |||
| otherwise) that contradict the conditions of this License, they do not | |||
| excuse you from the conditions of this License. If you cannot | |||
| distribute so as to satisfy simultaneously your obligations under this | |||
| License and any other pertinent obligations, then as a consequence you | |||
| may not distribute the Program at all. For example, if a patent | |||
| license would not permit royalty-free redistribution of the Program by | |||
| all those who receive copies directly or indirectly through you, then | |||
| the only way you could satisfy both it and this License would be to | |||
| refrain entirely from distribution of the Program. | |||
| If any portion of this section is held invalid or unenforceable under | |||
| any particular circumstance, the balance of the section is intended to | |||
| apply and the section as a whole is intended to apply in other | |||
| circumstances. | |||
| It is not the purpose of this section to induce you to infringe any | |||
| patents or other property right claims or to contest validity of any | |||
| such claims; this section has the sole purpose of protecting the | |||
| integrity of the free software distribution system, which is | |||
| implemented by public license practices. Many people have made | |||
| generous contributions to the wide range of software distributed | |||
| through that system in reliance on consistent application of that | |||
| system; it is up to the author/donor to decide if he or she is willing | |||
| to distribute software through any other system and a licensee cannot | |||
| impose that choice. | |||
| This section is intended to make thoroughly clear what is believed to | |||
| be a consequence of the rest of this License. | |||
| 8. If the distribution and/or use of the Program is restricted in | |||
| certain countries either by patents or by copyrighted interfaces, the | |||
| original copyright holder who places the Program under this License | |||
| may add an explicit geographical distribution limitation excluding | |||
| those countries, so that distribution is permitted only in or among | |||
| countries not thus excluded. In such case, this License incorporates | |||
| the limitation as if written in the body of this License. | |||
| 9. The Free Software Foundation may publish revised and/or new versions | |||
| of the General Public License from time to time. Such new versions will | |||
| be similar in spirit to the present version, but may differ in detail to | |||
| address new problems or concerns. | |||
| Each version is given a distinguishing version number. If the Program | |||
| specifies a version number of this License which applies to it and "any | |||
| later version", you have the option of following the terms and conditions | |||
| either of that version or of any later version published by the Free | |||
| Software Foundation. If the Program does not specify a version number of | |||
| this License, you may choose any version ever published by the Free Software | |||
| Foundation. | |||
| 10. If you wish to incorporate parts of the Program into other free | |||
| programs whose distribution conditions are different, write to the author | |||
| to ask for permission. For software which is copyrighted by the Free | |||
| Software Foundation, write to the Free Software Foundation; we sometimes | |||
| make exceptions for this. Our decision will be guided by the two goals | |||
| of preserving the free status of all derivatives of our free software and | |||
| of promoting the sharing and reuse of software generally. | |||
| NO WARRANTY | |||
| 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |||
| FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |||
| OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |||
| PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |||
| OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |||
| TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |||
| PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |||
| REPAIR OR CORRECTION. | |||
| 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |||
| REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |||
| INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |||
| OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |||
| TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |||
| YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |||
| PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |||
| POSSIBILITY OF SUCH DAMAGES. | |||
| END OF TERMS AND CONDITIONS | |||
| How to Apply These Terms to Your New Programs | |||
| If you develop a new program, and you want it to be of the greatest | |||
| possible use to the public, the best way to achieve this is to make it | |||
| free software which everyone can redistribute and change under these terms. | |||
| To do so, attach the following notices to the program. It is safest | |||
| to attach them to the start of each source file to most effectively | |||
| convey the exclusion of warranty; and each file should have at least | |||
| the "copyright" line and a pointer to where the full notice is found. | |||
| <one line to give the program's name and a brief idea of what it does.> | |||
| Copyright (C) <year> <name of author> | |||
| This program 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 2 of the License, or | |||
| (at your option) any later version. | |||
| 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 | |||
| Also add information on how to contact you by electronic and paper mail. | |||
| If the program is interactive, make it output a short notice like this | |||
| when it starts in an interactive mode: | |||
| Gnomovision version 69, Copyright (C) year name of author | |||
| Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
| This is free software, and you are welcome to redistribute it | |||
| under certain conditions; type `show c' for details. | |||
| The hypothetical commands `show w' and `show c' should show the appropriate | |||
| parts of the General Public License. Of course, the commands you use may | |||
| be called something other than `show w' and `show c'; they could even be | |||
| mouse-clicks or menu items--whatever suits your program. | |||
| You should also get your employer (if you work as a programmer) or your | |||
| school, if any, to sign a "copyright disclaimer" for the program, if | |||
| necessary. Here is a sample; alter the names: | |||
| Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |||
| `Gnomovision' (which makes passes at compilers) written by James Hacker. | |||
| <signature of Ty Coon>, 1 April 1989 | |||
| Ty Coon, President of Vice | |||
| This General Public License does not permit incorporating your program into | |||
| proprietary programs. If your program is a subroutine library, you may | |||
| consider it more useful to permit linking proprietary applications with the | |||
| library. If this is what you want to do, use the GNU Library General | |||
| Public License instead of this License. | |||
| @@ -0,0 +1,16 @@ | |||
| To install, cd to this directory, make, sudo make install | |||
| You need the shared libraries: | |||
| libzita-alsa-pcmi.0.2.0 | |||
| libclthreads.so.2.4.0 | |||
| libclxclient.so.3.9.0 | |||
| and the corresponding header files installed. These are available at | |||
| <http://kokkinizita.linuxaudio.org/linuxaudio/downloads/index.html> | |||
| You also need libfftw3f, which comes with most Linux distributions. | |||
| -- | |||
| FA | |||
| @@ -0,0 +1,101 @@ | |||
| JAAA -- Quick manual | |||
| ____________________ | |||
| Some buttons will light up yellow when you click on them, | |||
| and there will be at most one of those active at any time. | |||
| This indicates the 'current parameter', which in most | |||
| cases can be modified in a number of ways: | |||
| - by typing a new value into the text widget, followed by ENTER, | |||
| - by using the '<' or '>' buttons to decrement or increment, | |||
| - by using the mouse wheel, | |||
| - by mouse gestures inside the display area. | |||
| Input | |||
| ----- | |||
| Select on of the four inputs. | |||
| Frequency and Amplitude | |||
| ----------------------- | |||
| Frequency: | |||
| 'Min' and 'Max' set the min and max displayed frequencies. | |||
| If either of these is selected then | |||
| a horizontal Drag Left changes 'Min', | |||
| a horizontal Drag Right changes 'Max'. | |||
| 'Cent' is the frequency at the middle of the x-axis. | |||
| 'Span' is 'Max' - 'Min', changing this value preserves 'Cent'. | |||
| If either of these is selected then | |||
| a horizontal Drag Left changes 'Cent', | |||
| a horizontal Drag Right changes 'Span'. | |||
| 'Cent' can also be set by Clicking in the frequency axis scale. | |||
| Amplitude: | |||
| 'Max' is the maximum value on the y-axis. | |||
| 'Range' is the range of the y-axis. | |||
| If either of these is selected then | |||
| a vertical Drag Left changes 'Max', | |||
| a vertical Drag Right changes 'Range', | |||
| So for the last four mouse gestures, a Drag Left will scroll the | |||
| display, while a Drag Right will zoom in or out. Maybe I will add | |||
| and automatic selection of the axis based on the direction of the | |||
| mouse gesture. | |||
| Analyser | |||
| -------- | |||
| The analyser is based on a windowed FFT. Actually the windowing is performed | |||
| by convolution after the FFT, and combined with interpolation. The windowing | |||
| and interpolation ensure that displayed peaks will be accurate to 0.25 dB even | |||
| if the peak falls between the FFT bins. More accurate measurements can be made | |||
| using the markers (see below). | |||
| 'Bandw' sets the FFT length, and hence the bandwidth of the analyser. Depending | |||
| on this value, the size of the display and the frequency range, you may sometimes | |||
| see two traces. This happens when the resolution of the analyser is better than the | |||
| display, so that one pixel contains more than one analyser value. In that case, the | |||
| dark blue trace is the peak value over the frequency range represented by each pixel, | |||
| and lighter one is the average value. The first one is correct for discrete frequencies, | |||
| and the latter should be used to read noise densities. | |||
| There is no mouse gesture to change the bandwidth. | |||
| 'VidAv' or video average, when switched on, averages the measured energy over time. | |||
| This is mainly used to measure noise. The averaging lenght increases over time, to | |||
| a maxumum of 1000 iterations. Changing the input or bandwidth resets and restarts | |||
| the averaging. | |||
| 'Freeze' freezes the analyser, but not the display, so you can still scroll and | |||
| zoom or use the markers discussed below. | |||
| Markers | |||
| ------- | |||
| Markers are used in order to accurately read off values in the display. There can be | |||
| up to two markers, set by clicking at the desired frequency inside the display. | |||
| When there are two markers, the second one will move with each click, while the first | |||
| remains fixed. Measured values for the two markers, and their difference in frequency | |||
| and level are displayed in the upper left corner of the display. | |||
| 'Clear' clears the markers. | |||
| When 'Peak' is selected, clicking inside the display will set a marker at the nearest | |||
| peak. The exact frequency and level of the peak are found by interpolation, so the | |||
| frequency can be much more accurate than the FFT step, and the level corresponds to | |||
| the true peak value regardless of display or analyser resolution. | |||
| When 'Noise' is selected, clicking inside the display will set a noise marker. | |||
| The noise density (energy per Hz) is calculated and displayed. | |||
| @@ -0,0 +1,49 @@ | |||
| # -------------------------------------------------------------------------- | |||
| # | |||
| # Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| # | |||
| # This program 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 2 of the License, or | |||
| # (at your option) any later version. | |||
| # | |||
| # 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| # | |||
| # -------------------------------------------------------------------------- | |||
| PREFIX = /usr/local | |||
| SUFFIX := $(shell uname -m | sed -e 's/^unknown/$//' -e 's/^i.86/$//' -e 's/^x86_64/$/64/') | |||
| LIBDIR = lib$(SUFFIX) | |||
| VERSION = 0.8.4 | |||
| CPPFLAGS += -DVERSION=\"$(VERSION)\" -DPREFIX=\"$(PREFIX)\" -I/usr/include/freetype2 | |||
| CXXFLAGS += -O2 -Wall -MMD -MP | |||
| CXXFLAGS += -march=native | |||
| LDFLAGS += -L/usr/X11R6/$(LIBDIR) | |||
| LDLIBS += -lzita-alsa-pcmi -lclthreads -lclxclient -lpthread -lfftw3f -ljack -lasound -lpthread -lXft -lX11 -lrt | |||
| JAAA_O = jaaa.o styles.o spectwin.o audio.o rngen.o | |||
| jaaa: $(JAAA_O) | |||
| g++ $(LDFLAGS) -o $@ $(JAAA_O) $(LDLIBS) | |||
| $(JAAA_O): | |||
| -include $(JAAA_O:%.o=%.d) | |||
| install: jaaa | |||
| install -Dm 755 jaaa $(DESTDIR)$(PREFIX)/bin/jaaa | |||
| uninstall: | |||
| rm -f $(DESTDIR)$(PREFIX)/bin/jaaa | |||
| clean: | |||
| /bin/rm -f *~ *.o *.a *.d *.so jaaa | |||
| @@ -0,0 +1,261 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #include <math.h> | |||
| #include "audio.h" | |||
| #include "messages.h" | |||
| Audio::Audio (ITC_ctrl *cmain, const char *name) : | |||
| A_thread ("Audio"), | |||
| _name (name), | |||
| _cmain (cmain), | |||
| _run_jack (0), | |||
| _ncapt (8), | |||
| _nplay (8), | |||
| _input (-1), | |||
| _data (0), | |||
| _outs (0) | |||
| { | |||
| } | |||
| Audio::~Audio (void) | |||
| { | |||
| if (_run_jack) close_jack (); | |||
| delete[] _outs; | |||
| } | |||
| void Audio::init (void) | |||
| { | |||
| int i; | |||
| for (i = 0; i < LSINE; i++) | |||
| { | |||
| _sine [i] = sin (2 * M_PI * i / LSINE); | |||
| } | |||
| _sine [LSINE] = 0; | |||
| _g_bits = 0; | |||
| _a_noise = 0.0; | |||
| _a_sine = 0.0; | |||
| _f_sine = 0.0; | |||
| _p_sine = 0.0; | |||
| } | |||
| void Audio::thr_main (void) | |||
| { | |||
| put_event (EV_EXIT); | |||
| } | |||
| void Audio::init_jack (const char *server) | |||
| { | |||
| char s [16]; | |||
| int opts; | |||
| jack_status_t stat; | |||
| opts = JackNoStartServer; | |||
| if (server) opts |= JackServerName; | |||
| if ((_jack_handle = jack_client_open (_name, (jack_options_t) opts, &stat, server)) == 0) | |||
| { | |||
| fprintf (stderr, "Can't connect to JACK\n"); | |||
| exit (1); | |||
| } | |||
| jack_set_process_callback (_jack_handle, jack_static_callback, (void *)this); | |||
| jack_on_shutdown (_jack_handle, jack_static_shutdown, (void *)this); | |||
| for (int i = 0; i < _nplay; i++) | |||
| { | |||
| sprintf(s, "out_%d", i + 1); | |||
| _jack_out [i] = jack_port_register (_jack_handle, s, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
| } | |||
| for (int i = 0; i < _ncapt; i++) | |||
| { | |||
| sprintf(s, "in_%d", i + 1); | |||
| _jack_in [i] = jack_port_register (_jack_handle, s, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); | |||
| } | |||
| _outs = new float [4096]; | |||
| init (); | |||
| if (jack_activate (_jack_handle)) | |||
| { | |||
| fprintf(stderr, "Can't activate JACK"); | |||
| exit (1); | |||
| } | |||
| _fsamp = jack_get_sample_rate (_jack_handle); | |||
| _fsize = jack_get_buffer_size (_jack_handle); | |||
| _name = jack_get_client_name (_jack_handle); | |||
| _run_jack = true; | |||
| _cmain->put_event (EV_MESG, new M_jinfo (_fsamp, _fsize, _name)); | |||
| } | |||
| void Audio::close_jack () | |||
| { | |||
| jack_deactivate (_jack_handle); | |||
| for (int i = 0; i < _nplay; i++) jack_port_unregister(_jack_handle, _jack_out[i]); | |||
| for (int i = 0; i < _ncapt; i++) jack_port_unregister(_jack_handle, _jack_in[i]); | |||
| jack_client_close (_jack_handle); | |||
| } | |||
| void Audio::jack_static_shutdown (void *arg) | |||
| { | |||
| return ((Audio *) arg)->jack_shutdown (); | |||
| } | |||
| void Audio::jack_shutdown (void) | |||
| { | |||
| _cmain->put_event (EV_JACK); | |||
| } | |||
| int Audio::jack_static_callback (jack_nframes_t nframes, void *arg) | |||
| { | |||
| return ((Audio *) arg)->jack_callback (nframes); | |||
| } | |||
| int Audio::jack_callback (jack_nframes_t nframes) | |||
| { | |||
| unsigned long b, m, n; | |||
| int i; | |||
| float *p; | |||
| if (_data && _input >= 0) | |||
| { | |||
| p = (float *)(jack_port_get_buffer (_jack_in [_input], nframes)); | |||
| m = nframes; | |||
| n = _size - _dind; | |||
| if (m >= n) | |||
| { | |||
| memcpy (_data + _dind, p, sizeof(jack_default_audio_sample_t) * n); | |||
| _dind = 0; | |||
| p += n; | |||
| m -= n; | |||
| } | |||
| if (m) | |||
| { | |||
| memcpy (_data + _dind, p, sizeof(jack_default_audio_sample_t) * m); | |||
| _dind += m; | |||
| } | |||
| _scnt += nframes; | |||
| } | |||
| generate (nframes); | |||
| b = _g_bits & 255; | |||
| for (i = 0; i < _nplay; i++, b >>= 1) | |||
| { | |||
| p = (float *)(jack_port_get_buffer (_jack_out [i], nframes)); | |||
| if (b & 1) memcpy (p, _outs, sizeof(jack_default_audio_sample_t) * nframes); | |||
| else memset (p, 0, sizeof(jack_default_audio_sample_t) * nframes); | |||
| } | |||
| process (); | |||
| return 0; | |||
| } | |||
| void Audio::process (void) | |||
| { | |||
| int k; | |||
| ITC_mesg *M; | |||
| if (_data) | |||
| { | |||
| k = _scnt / _step; | |||
| if (k && _cmain->put_event_try (EV_TRIG, k) == ITC_ctrl::NO_ERROR) _scnt -= k * _step; | |||
| } | |||
| if (get_event_nowait (1 << EV_MESG) == EV_MESG) | |||
| { | |||
| M = get_message (); | |||
| if (M->type () == M_BUFFP) | |||
| { | |||
| M_buffp *Z = (M_buffp *) M; | |||
| _data = Z->_data; | |||
| _size = Z->_size; | |||
| _step = Z->_step; | |||
| _dind = 0; | |||
| _scnt = 0; | |||
| } | |||
| else if (M->type () == M_INPUT) | |||
| { | |||
| M_input *Z = (M_input *) M; | |||
| _input = Z->_input; | |||
| if (_input >= _ncapt) _input = -1; | |||
| } | |||
| else if (M->type () == M_GENPAR) | |||
| { | |||
| M_genpar *Z = (M_genpar *) M; | |||
| _g_bits = Z->_g_bits; | |||
| _a_noise = sqrt (0.5) * pow (10.0, 0.05 * Z->_a_noise); | |||
| _a_sine = pow (10.0, 0.05 * Z->_a_sine); | |||
| _f_sine = LSINE * Z->_f_sine / _fsamp; | |||
| } | |||
| M->recover (); | |||
| } | |||
| } | |||
| void Audio::generate (int size) | |||
| { | |||
| int i, j; | |||
| float a, p, r; | |||
| if (size > 4096) size = 4096; | |||
| memset (_outs, 0, size * sizeof (float)); | |||
| if (_g_bits & M_genpar::WNOISE) | |||
| { | |||
| for (i = 0; i < size; i++) | |||
| { | |||
| _outs [i] += _a_noise * _rngen.grandf (); | |||
| } | |||
| } | |||
| if (_g_bits & M_genpar::SINE) | |||
| { | |||
| p = _p_sine; | |||
| for (i = 0; i < size; i++) | |||
| { | |||
| j = (int) p; | |||
| if (j == LSINE) a = 0; | |||
| else | |||
| { | |||
| r = p - j; | |||
| a = (1.0 - r) * _sine [j] + r * _sine [j + 1]; | |||
| } | |||
| _outs [i] += _a_sine * a; | |||
| p += _f_sine; | |||
| if (p >= LSINE) p -= LSINE; | |||
| } | |||
| _p_sine = p; | |||
| } | |||
| } | |||
| @@ -0,0 +1,81 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #include <stdlib.h> | |||
| #include <math.h> | |||
| #include <clthreads.h> | |||
| #include "CarlaNativeJack.h" | |||
| #include "rngen.h" | |||
| class Audio : public A_thread | |||
| { | |||
| public: | |||
| Audio (ITC_ctrl *cmain, const char *name); | |||
| virtual ~Audio (void); | |||
| void init_jack (const char *server); | |||
| private: | |||
| enum { LSINE = 4096, LRAND = 4096, MRAND = LRAND - 1 }; | |||
| virtual void thr_main (void); | |||
| void init (void); | |||
| void process (void); | |||
| void generate (int size); | |||
| void close_jack (void); | |||
| void jack_shutdown (void); | |||
| int jack_callback (jack_nframes_t nframes); | |||
| const char *_name; | |||
| ITC_ctrl *_cmain; | |||
| volatile bool _run_jack; | |||
| jack_client_t *_jack_handle; | |||
| jack_port_t *_jack_in [8]; | |||
| jack_port_t *_jack_out [8]; | |||
| unsigned long _fsamp; | |||
| unsigned long _fsize; | |||
| int _ncapt; | |||
| int _nplay; | |||
| int _input; | |||
| float *_data; | |||
| int _dind; | |||
| int _size; | |||
| int _step; | |||
| int _scnt; | |||
| float _sine [LSINE + 1]; | |||
| float *_outs; | |||
| int _g_bits; | |||
| float _a_noise; | |||
| float _a_sine; | |||
| float _f_sine; | |||
| float _p_sine; | |||
| Rngen _rngen; | |||
| static void jack_static_shutdown (void *arg); | |||
| static int jack_static_callback (jack_nframes_t nframes, void *arg); | |||
| }; | |||
| @@ -0,0 +1,175 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <clthreads.h> | |||
| #include <clxclient.h> | |||
| #include <sys/mman.h> | |||
| #include "messages.h" | |||
| #include "spectwin.h" | |||
| #include "audio.h" | |||
| #define NOPTS 10 | |||
| #define CP (char *) | |||
| XrmOptionDescRec options [NOPTS] = | |||
| { | |||
| {CP"-h", CP".help", XrmoptionNoArg, CP"true" }, | |||
| {CP"-J", CP".jack", XrmoptionNoArg, CP"true" }, | |||
| {CP"-s", CP".server", XrmoptionSepArg, 0 }, | |||
| {CP"-A", CP".alsa", XrmoptionNoArg, CP"true" }, | |||
| {CP"-d", CP".device", XrmoptionSepArg, 0 }, | |||
| {CP"-C", CP".capture", XrmoptionSepArg, 0 }, | |||
| {CP"-P", CP".playback", XrmoptionSepArg, 0 }, | |||
| {CP"-r", CP".fsamp", XrmoptionSepArg, 0 }, | |||
| {CP"-p", CP".period", XrmoptionSepArg, 0 }, | |||
| {CP"-n", CP".nfrags", XrmoptionSepArg, 0 } | |||
| }; | |||
| static void help (void) | |||
| { | |||
| fprintf (stderr, "\nJaaa-%s\n\n", VERSION); | |||
| fprintf (stderr, " (C) 2004-2010 Fons Adriaensen <fons@kokkinizita.net>\n\n"); | |||
| fprintf (stderr, "Options:\n"); | |||
| fprintf (stderr, " -h Display this text\n"); | |||
| fprintf (stderr, " -name <name> Jack and X11 name\n"); | |||
| fprintf (stderr, " -J Use JACK, with options:\n"); | |||
| fprintf (stderr, " -s <server> Select Jack server\n"); | |||
| fprintf (stderr, " -A Use ALSA, with options:\n"); | |||
| fprintf (stderr, " -d <device> Alsa device [hw:0]\n"); | |||
| fprintf (stderr, " -C <device> Capture device\n"); | |||
| fprintf (stderr, " -P <device> Playback device\n"); | |||
| fprintf (stderr, " -r <rate> Sample frequency [48000]\n"); | |||
| fprintf (stderr, " -p <period> Period size [1024]\n"); | |||
| fprintf (stderr, " -n <nfrags> Number of fragments [2]\n\n"); | |||
| fprintf (stderr, " Either -J or -A is required.\n\n"); | |||
| exit (1); | |||
| } | |||
| int main (int argc, char *argv []) | |||
| { | |||
| X_resman xrm; | |||
| X_display *display; | |||
| X_handler *xhandler; | |||
| X_rootwin *rootwin; | |||
| Spectwin *mainwin; | |||
| Audio *driver; | |||
| ITC_ctrl itcc; | |||
| // Initialse resource database | |||
| xrm.init (&argc, argv, CP"jaaa", options, NOPTS); | |||
| if (xrm.getb (".help", 0)) help (); | |||
| // Open display | |||
| display = new X_display (xrm.get (".display", 0)); | |||
| if (display->dpy () == 0) | |||
| { | |||
| fprintf (stderr, "Can't open display !\n"); | |||
| delete display; | |||
| exit (1); | |||
| } | |||
| // Open audio interface | |||
| driver = new Audio (&itcc, xrm.rname ()); | |||
| if (xrm.getb (".jack", 0)) | |||
| { | |||
| driver->init_jack (xrm.get (".server", 0)); | |||
| } | |||
| else if (xrm.getb (".alsa", 0)) | |||
| { | |||
| const char *p, *adev, *capt, *play; | |||
| int fsamp, period, nfrags; | |||
| p = xrm.get (".fsamp", 0); | |||
| if (! p || sscanf (p, "%d", &fsamp) != 1) fsamp = 48000; | |||
| p = xrm.get (".period", 0); | |||
| if (! p || sscanf (p, "%d", &period) != 1) period = 1024; | |||
| p = xrm.get (".nfrags", 0); | |||
| if (! p || sscanf (p, "%d", &nfrags) != 1) nfrags = 2; | |||
| adev = xrm.get (".device", "hw:0"); | |||
| capt = xrm.get (".capture", 0); | |||
| play = xrm.get (".playback", 0); | |||
| if (!capt && !play) capt = play = adev; | |||
| driver->init_alsa (play, capt, fsamp, period, nfrags, 4, 4); | |||
| } | |||
| else help (); | |||
| // Initialise resources and create windows | |||
| init_styles (display, &xrm); | |||
| rootwin = new X_rootwin (display); | |||
| mainwin = new Spectwin (rootwin, &xrm, driver); | |||
| // Create X handler | |||
| xhandler = new X_handler (display, &itcc, EV_X11); | |||
| xhandler->next_event (); | |||
| XFlush (display->dpy ()); | |||
| // Try to lock memory | |||
| if (mlockall (MCL_CURRENT | MCL_FUTURE)) | |||
| { | |||
| fprintf (stderr, "Warning: memory lock failed.\n"); | |||
| } | |||
| // Enter main loop | |||
| while (mainwin->running ()) | |||
| { | |||
| switch (itcc.get_event ()) | |||
| { | |||
| case EV_TRIG: | |||
| mainwin->handle_trig (); | |||
| rootwin->handle_event (); | |||
| XFlush (display->dpy ()); | |||
| break; | |||
| case EV_JACK: | |||
| mainwin->handle_term (); | |||
| break; | |||
| case EV_MESG: | |||
| mainwin->handle_mesg (itcc.get_message ()); | |||
| rootwin->handle_event (); | |||
| XFlush (display->dpy ()); | |||
| break; | |||
| case EV_X11: | |||
| rootwin->handle_event (); | |||
| xhandler->next_event (); | |||
| break; | |||
| } | |||
| } | |||
| // Cleanup | |||
| delete xhandler; | |||
| delete driver; | |||
| delete mainwin; | |||
| delete rootwin; | |||
| delete display; | |||
| return 0; | |||
| } | |||
| @@ -0,0 +1,98 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #ifndef __MESSAGES_H | |||
| #define __MESSAGES_H | |||
| #include <clthreads.h> | |||
| #define EV_MESG 0 | |||
| #define EV_X11 16 | |||
| #define EV_JACK 29 | |||
| #define EV_TRIG 30 | |||
| #define EV_EXIT 31 | |||
| #define M_BUFFP 1 | |||
| #define M_INPUT 2 | |||
| #define M_JINFO 3 | |||
| #define M_GENPAR 4 | |||
| class M_buffp : public ITC_mesg | |||
| { | |||
| public: | |||
| M_buffp (float *data, int size, int step) : | |||
| ITC_mesg (M_BUFFP), | |||
| _data (data), | |||
| _size (size), | |||
| _step (step) {} | |||
| float *_data; | |||
| int _size; | |||
| int _step; | |||
| }; | |||
| class M_input : public ITC_mesg | |||
| { | |||
| public: | |||
| M_input (int input) : | |||
| ITC_mesg (M_INPUT), | |||
| _input (input) {} | |||
| int _input; | |||
| }; | |||
| class M_jinfo : public ITC_mesg | |||
| { | |||
| public: | |||
| M_jinfo (unsigned long fsamp, unsigned long fsize, const char *jname) : | |||
| ITC_mesg (M_JINFO), | |||
| _fsamp (fsamp), | |||
| _fsize (fsize), | |||
| _jname (jname) {} | |||
| unsigned long _fsamp; | |||
| unsigned long _fsize; | |||
| const char *_jname; | |||
| }; | |||
| class M_genpar : public ITC_mesg | |||
| { | |||
| public: | |||
| enum { WNOISE = 256, SINE = 512 }; | |||
| M_genpar (void) : | |||
| ITC_mesg (M_GENPAR) {} | |||
| int _g_bits; | |||
| float _a_noise; | |||
| float _a_sine; | |||
| float _f_sine; | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,265 @@ | |||
| // ---------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2003-2010 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ---------------------------------------------------------------------- | |||
| #ifndef __PRBSGEN_H | |||
| #define __PRBSGEN_H | |||
| #include <assert.h> | |||
| #include <sys/types.h> | |||
| #include <stdint.h> | |||
| //--------------------------------------------------------------------------- | |||
| // | |||
| // Description: | |||
| // Pseudo random binary sequence generator using polynomial | |||
| // division in GF (2). | |||
| // | |||
| // There are two ways to built such a generator. Both use some | |||
| // form of shift register. | |||
| // | |||
| // 1. The first type feeds back the parity (XOR) of the taps corresponding to | |||
| // the non-zero elements of the polynomial into the input of the register. | |||
| // This is the most efficient way to do it in hardware. | |||
| // | |||
| // 2. In the seond form, when the bit shifted out is 1, the contents of the | |||
| // register are XORed with a bit pattern representing the polynomial. | |||
| // This is the best way to do it in software. | |||
| // | |||
| // Mutatis mutandis the two forms are equivalent. Any sequence that can be | |||
| // generated by one of the realisations can also be produced by the other. | |||
| // This software obviously uses the second form. It can use any polynomial | |||
| // up to (and including) a degree of 32. | |||
| // | |||
| // | |||
| // set_poly (p) | |||
| // | |||
| // Defines the polynomial to be used. The value of p is found from the | |||
| // sequence of coefficients (0 or 1) of the polynomial starting with the | |||
| // constant term, and dropping the highest one | |||
| // | |||
| // 0 1 2 3 4 5 6 7 | |||
| // Example: P = x^7 + x^6 + 1 --> 1 0 0 0 0 0 1 1 --> 1000001 --> 0x41 | |||
| // | |||
| // To emulate the first form described above, start with the highest | |||
| // exponent and drop the constant term. | |||
| // | |||
| // 7 6 5 4 3 2 1 0 | |||
| // Example: P = x^7 + x^6 + 1 --> 1 1 0 0 0 0 0 1 --> 1100000 --> 0x60 | |||
| // | |||
| // Also sets the state to all ones. | |||
| // | |||
| // | |||
| // set_state (x) | |||
| // | |||
| // Sets the initial state to x. | |||
| // | |||
| // | |||
| // step () | |||
| // | |||
| // Returns the next pseudo random bit. | |||
| // | |||
| // | |||
| // sync_forw (x) | |||
| // | |||
| // This sets the generator in a state as if the last N (= degree) bits | |||
| // were those defined by x (the LSB of x represents the oldest bit). | |||
| // This can be used to synchronise a BER counter to a received bit stream, | |||
| // or to set the initial state when emulating a generator of the first form | |||
| // when the output is taken from the feedback. | |||
| // | |||
| // | |||
| // sync_back (x) | |||
| // | |||
| // This sets the generator in a state so that the first N (= degree) output | |||
| // bits will be those defined by x (the LSB of x will be the first output bit). | |||
| // This can be used to set the initial state when emulating a generator of | |||
| // the first form when the output is taken from the shifted out bit. | |||
| // | |||
| // | |||
| //---------------------------------------------------------------------------== | |||
| class Prbsgen | |||
| { | |||
| public: | |||
| enum | |||
| { | |||
| // Some polynomials for maximum length seqeunces. | |||
| G7 = 0x00000041, | |||
| G8 = 0x0000008E, | |||
| G15 = 0x00004001, | |||
| G16 = 0x00008016, | |||
| G23 = 0x00400010, | |||
| G24 = 0x0080000D, | |||
| G31 = 0x40000004, | |||
| G32 = 0x80000057, | |||
| }; | |||
| Prbsgen (void); | |||
| void set_poly (uint32_t poly); | |||
| void set_stat (uint32_t stat); | |||
| void sync_forw (uint32_t bits); | |||
| void sync_back (uint32_t bits); | |||
| int step (void); | |||
| void crc_in (int b); | |||
| int crc_out (void); | |||
| uint32_t stat (void) const; | |||
| uint32_t poly (void) const; | |||
| uint32_t mask (void) const; | |||
| uint32_t hbit (void) const; | |||
| int degr (void) const; | |||
| ~Prbsgen (void); | |||
| private: | |||
| uint32_t _stat; | |||
| uint32_t _poly; | |||
| uint32_t _mask; | |||
| uint32_t _hbit; | |||
| int _degr; | |||
| }; | |||
| inline Prbsgen::Prbsgen (void) | |||
| : _stat (0), _poly (0), _mask (0), _degr (0) | |||
| { | |||
| } | |||
| inline Prbsgen::~Prbsgen (void) | |||
| { | |||
| } | |||
| inline void Prbsgen::set_poly (uint32_t poly) | |||
| { | |||
| assert (poly != 0); | |||
| _poly = poly; | |||
| _mask = 0; | |||
| _degr = 0; | |||
| while (_mask < _poly) | |||
| { | |||
| _mask = (_mask << 1) | 1; | |||
| _degr += 1; | |||
| } | |||
| _stat = _mask; | |||
| _hbit = (_mask >> 1) + 1; | |||
| } | |||
| inline void Prbsgen::set_stat (uint32_t stat) | |||
| { | |||
| assert (_poly != 0); | |||
| _stat = stat & _mask; | |||
| assert (_stat != 0); | |||
| } | |||
| inline int Prbsgen::step (void) | |||
| { | |||
| int bit; | |||
| assert (_poly != 0); | |||
| bit = _stat & 1; | |||
| _stat >>= 1; | |||
| if (bit) _stat ^= _poly; | |||
| return bit; | |||
| } | |||
| inline void Prbsgen::sync_forw (uint32_t bits) | |||
| { | |||
| assert (_poly != 0); | |||
| for (int i = 0; i < _degr; i++) | |||
| { | |||
| _stat >>= 1; | |||
| if (bits & 1) _stat ^= _poly; | |||
| bits >>= 1; | |||
| } | |||
| } | |||
| inline void Prbsgen::sync_back (uint32_t bits) | |||
| { | |||
| assert (_poly != 0); | |||
| _stat = 0; | |||
| for (int h = _hbit; h; h >>= 1) | |||
| { | |||
| if (bits & h) _stat ^= _poly; | |||
| _stat <<= 1; | |||
| } | |||
| _stat ^= bits; | |||
| _stat &= _mask; | |||
| } | |||
| inline void Prbsgen::crc_in (int b) | |||
| { | |||
| int bit; | |||
| assert (_poly != 0); | |||
| bit = (_stat & 1) ^ b; | |||
| _stat >>= 1; | |||
| if (bit) _stat ^= _poly; | |||
| } | |||
| inline int Prbsgen::crc_out (void) | |||
| { | |||
| int bit; | |||
| assert (_poly != 0); | |||
| bit = (_stat & 1); | |||
| _stat >>= 1; | |||
| return bit; | |||
| } | |||
| inline uint32_t Prbsgen::stat (void) const { return _stat; } | |||
| inline uint32_t Prbsgen::poly (void) const { return _poly; } | |||
| inline uint32_t Prbsgen::mask (void) const { return _mask; } | |||
| inline uint32_t Prbsgen::hbit (void) const { return _hbit; } | |||
| inline int Prbsgen::degr (void) const { return _degr; } | |||
| #endif | |||
| @@ -0,0 +1,153 @@ | |||
| // ---------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2003-2010 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ---------------------------------------------------------------------- | |||
| #include <math.h> | |||
| #include <time.h> | |||
| #include "rngen.h" | |||
| const double Rngen::_p31 = 2147483648.0; | |||
| const double Rngen::_p32 = 4294967296.0; | |||
| const float Rngen::_p31f = 2147483648.0f; | |||
| const float Rngen::_p32f = 4294967296.0f; | |||
| Rngen::Rngen (void) | |||
| { | |||
| init (0); | |||
| } | |||
| Rngen::~Rngen (void) | |||
| { | |||
| } | |||
| void Rngen::init (uint32_t s) | |||
| { | |||
| int i, j; | |||
| Prbsgen G; | |||
| if (s == 0) s = time (0); | |||
| G.set_poly (Prbsgen::G32); | |||
| G.set_stat (s); | |||
| for (i = 0; i < 55; i++) | |||
| { | |||
| G.step (); | |||
| j = G.stat () & 4095; | |||
| while (j--) G.step (); | |||
| _a [i] = G.stat (); | |||
| } | |||
| _i = 0; | |||
| _md = false; | |||
| _mf = false; | |||
| } | |||
| double Rngen::grand (void) | |||
| { | |||
| double a, b, r; | |||
| if (_md) | |||
| { | |||
| _md = false; | |||
| return _vd; | |||
| } | |||
| do | |||
| { | |||
| a = irand () / _p31 - 1.0; | |||
| b = irand () / _p31 - 1.0; | |||
| r = a * a + b * b; | |||
| } | |||
| while ((r > 1.0) || (r < 1e-20)); | |||
| r = sqrt (-2.0 * log (r) / r); | |||
| _md = true; | |||
| _vd = r * b; | |||
| return r * a; | |||
| } | |||
| void Rngen::grand (double *x, double *y) | |||
| { | |||
| double a, b, r; | |||
| do | |||
| { | |||
| a = irand () / _p31 - 1.0; | |||
| b = irand () / _p31 - 1.0; | |||
| r = a * a + b * b; | |||
| } | |||
| while ((r > 1.0) || (r < 1e-20)); | |||
| r = sqrt (-log (r) / r); | |||
| *x = r * a; | |||
| *y = r * b; | |||
| } | |||
| float Rngen::grandf (void) | |||
| { | |||
| float a, b, r; | |||
| if (_mf) | |||
| { | |||
| _mf = false; | |||
| return _vf; | |||
| } | |||
| do | |||
| { | |||
| a = irand () / _p31f - 1.0f; | |||
| b = irand () / _p31f - 1.0f; | |||
| r = a * a + b * b; | |||
| } | |||
| while ((r > 1.0f) || (r < 1e-20f)); | |||
| r = sqrtf (-2.0f * logf (r) / r); | |||
| _mf = true; | |||
| _vf = r * b; | |||
| return r * a; | |||
| } | |||
| void Rngen::grandf (float *x, float *y) | |||
| { | |||
| float a, b, r; | |||
| do | |||
| { | |||
| a = irand () / _p31f - 1.0f; | |||
| b = irand () / _p31f - 1.0f; | |||
| r = a * a + b * b; | |||
| } | |||
| while ((r > 1.0f) || (r < 1e-20f)); | |||
| r = sqrtf (-logf (r) / r); | |||
| *x = r * a; | |||
| *y = r * b; | |||
| } | |||
| @@ -0,0 +1,74 @@ | |||
| // ---------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2003-2010 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ---------------------------------------------------------------------- | |||
| #ifndef __RNGEN_H | |||
| #define __RNGEN_H | |||
| #include "prbsgen.h" | |||
| class Rngen | |||
| { | |||
| public: | |||
| Rngen (void); | |||
| void init (uint32_t seed); | |||
| uint32_t irand (void) | |||
| { | |||
| uint32_t r; | |||
| if (++_i == 55) _i = 0; | |||
| if (_i < 24) r = _a [_i] += _a [_i + 31]; | |||
| else r = _a [_i] += _a [_i - 24]; | |||
| return r; | |||
| } | |||
| double urand (void) { return irand () / _p32; } | |||
| double grand (void); | |||
| void grand (double *x, double *y); | |||
| float urandf (void) { return irand () / _p32f; } | |||
| float grandf (void); | |||
| void grandf (float *x, float *y); | |||
| ~Rngen (void); | |||
| Rngen (const Rngen&); // disabled, not to be used | |||
| Rngen& operator=(const Rngen&); // disabled, not to be used | |||
| private: | |||
| uint32_t _a [55]; | |||
| int _i; | |||
| bool _md; | |||
| bool _mf; | |||
| double _vd; | |||
| float _vf; | |||
| static const double _p31; | |||
| static const double _p32; | |||
| static const float _p31f; | |||
| static const float _p32f; | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,209 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #ifndef __SPECTWIN_H | |||
| #define __SPECTWIN_H | |||
| #include <clxclient.h> | |||
| #include <clthreads.h> | |||
| #include <fftw3.h> | |||
| #include "styles.h" | |||
| #define XPOS 100 | |||
| #define YPOS 100 | |||
| #define XMIN 600 | |||
| #define YMIN 430 | |||
| #define XDEF 600 | |||
| #define YDEF 450 | |||
| #define XMAX 1200 | |||
| #define YMAX 900 | |||
| #define LMAR 40 | |||
| #define RMAR 80 | |||
| #define TMAR 8 | |||
| #define BMAR 24 | |||
| class Spectdata | |||
| { | |||
| public: | |||
| enum { MK1_SET = 1, MK1_NSE = 2, MK2_SET = 4, MK2_NSE = 8, RESET = 16, PEAKH = 32, FREEZE = 64, YP_VAL = 256, YM_VAL = 512 }; | |||
| Spectdata (int size) | |||
| { | |||
| _yp = new float [size]; | |||
| _ym = new float [size]; | |||
| } | |||
| ~Spectdata (void) | |||
| { | |||
| delete[] _yp; | |||
| delete[] _ym; | |||
| } | |||
| int _npix; | |||
| int _bits; | |||
| int _avcnt; | |||
| int _avmax; | |||
| float _bw; | |||
| float _f0; | |||
| float _f1; | |||
| float _mk1f; | |||
| float _mk1p; | |||
| float _mk2f; | |||
| float _mk2p; | |||
| char *_xf; | |||
| float *_yp; | |||
| float *_ym; | |||
| }; | |||
| class Spectwin : public X_window, public X_callback | |||
| { | |||
| public: | |||
| Spectwin (X_window *parent, X_resman *xres, ITC_ctrl *audio); | |||
| ~Spectwin (void); | |||
| bool running (void) const { return _running; } | |||
| void handle_trig (void); | |||
| void handle_term (void) { _running = 0; } | |||
| void handle_mesg (ITC_mesg *); | |||
| private: | |||
| enum | |||
| { | |||
| IP1, IP2, IP3, IP4, | |||
| IP5, IP6, IP7, IP8, | |||
| BANDW, VIDAV, PEAKH, FREEZ, | |||
| MCLR, MPEAK, MNSE, | |||
| FMIN, FMAX, FCENT, FSPAN, | |||
| AMAX, ASPAN, | |||
| BTUP, BTDN, | |||
| OP1, OP2, OP3, OP4, | |||
| OP5, OP6, OP7, OP8, | |||
| NSACT, SIACT, | |||
| NSLEV, SILEV, SFREQ, | |||
| NBUTT | |||
| }; | |||
| enum | |||
| { | |||
| FFT_MIN = 256, | |||
| FFT_MAX = 1024 * 256, | |||
| BUF_LEN = 2 * FFT_MAX, | |||
| INP_MAX = BUF_LEN - FFT_MAX / 2, | |||
| INP_LEN = 4096 | |||
| }; | |||
| virtual void handle_event (XEvent *xe); | |||
| virtual void handle_callb (int, X_window*, _XEvent*); | |||
| void message (XClientMessageEvent *); | |||
| void expose (XExposeEvent *); | |||
| void resize (XConfigureEvent *); | |||
| void redraw (void); | |||
| void update (void); | |||
| void bpress (XButtonEvent *); | |||
| void motion (XPointerMovedEvent *); | |||
| void brelse (XButtonEvent *); | |||
| void set_fsamp (float fsamp, bool symm); | |||
| void set_input (int i); | |||
| void set_output (int i); | |||
| void set_param (int i); | |||
| void mod_param (bool inc); | |||
| void set_bw (float); | |||
| void set_f0 (float); | |||
| void set_f1 (float); | |||
| void set_fc (float); | |||
| void set_fs (float); | |||
| void set_a1 (float); | |||
| void set_ar (float); | |||
| void set_a_ns (float); | |||
| void set_a_si (float); | |||
| void set_f_si (float); | |||
| void send_genp (void); | |||
| void set_mark (float f, bool nse); | |||
| void clr_mark (void); | |||
| void show_param (void); | |||
| void plot_fscale (void); | |||
| void plot_ascale (void); | |||
| void plot_clear (void); | |||
| void plot_grid (void); | |||
| void plot_spect (Spectdata *); | |||
| void plot_annot (Spectdata *); | |||
| void alloc_fft (Spectdata *); | |||
| void calc_spect (Spectdata *); | |||
| float calcfreq (int x); | |||
| float conv0 (fftwf_complex *); | |||
| float conv1 (fftwf_complex *); | |||
| void calc_noise (float *f, float *p); | |||
| void calc_peak (float *f, float *p, float r); | |||
| void print_note (char *s, float f); | |||
| int _xs, _ys; | |||
| int _running; | |||
| Atom _atoms [2]; | |||
| Atom _wmpro; | |||
| X_window *_plotwin; | |||
| Pixmap _plotmap; | |||
| GC _plotgct; | |||
| X_button *_butt [NBUTT]; | |||
| X_textip *_txt1; | |||
| Spectdata *_spect; | |||
| ITC_ctrl *_audio; | |||
| int _input; | |||
| int _drag; | |||
| int _xd, _yd; | |||
| int _p_ind; | |||
| float _p_val; | |||
| float _fsamp; | |||
| float _funit; | |||
| const char *_fform; | |||
| float _bmin, _bmax, _bw; | |||
| float _fmin, _fmax, _f0, _f1, _fc, _fm, _df; | |||
| float _amin, _amax, _a0, _a1, _da; | |||
| float _a_ns, _a_si, _f_si, _a_pu; | |||
| int _g_bits; | |||
| int _ngx, _grx [40]; | |||
| int _ngy, _gry [20]; | |||
| fftwf_complex *_trbuf; | |||
| fftwf_plan _fftplan; | |||
| float *_ipbuf; | |||
| float *_fftbuf; | |||
| float *_power; | |||
| int _fftlen; | |||
| int _ipmod; | |||
| int _ipcnt; | |||
| float _ptot; | |||
| const static char *_formats [9]; | |||
| const static char *_notes [12]; | |||
| friend class JaaaPlugin; | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,135 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #include "styles.h" | |||
| struct colors Colors; | |||
| struct fonts Fonts; | |||
| struct xft_colors XftColors; | |||
| struct xft_fonts XftFonts; | |||
| X_button_style Bst0, Bst1, BstA, BstB, BstM; | |||
| X_textln_style Tst0, Tst1; | |||
| void init_styles (X_display *disp, X_resman *xrm) | |||
| { | |||
| Colors.black = disp->blackpixel (); | |||
| Colors.white = disp->whitepixel (); | |||
| Colors.main_bg = disp->alloc_color (xrm->get (".color.main.bg", "#e4e0d4"), Colors.white); | |||
| Colors.main_ds = disp->alloc_color (xrm->get (".color.main.ds", "gray20"), Colors.black); | |||
| Colors.main_ls = disp->alloc_color (xrm->get (".color.main.ls", "white"), Colors.white); | |||
| Colors.text_ed = disp->alloc_color (xrm->get (".color.text.ed", "yellow"), Colors.white); | |||
| Colors.text_ca = disp->alloc_color (xrm->get (".color.text.ca", "black"), Colors.black); | |||
| Colors.spect_bg = disp->alloc_color (xrm->get (".color.spect.bg", "white"), Colors.white); | |||
| Colors.spect_gr = disp->alloc_color (xrm->get (".color.spect.gr", "gray80"), Colors.white); | |||
| Colors.spect_mk = disp->alloc_color (xrm->get (".color.spect.mk", "red"), Colors.black); | |||
| Colors.spect_trA = disp->alloc_color (xrm->get (".color.spect.trA", "blue"), Colors.black); | |||
| Colors.spect_pkA = disp->alloc_color (xrm->get (".color.spect.pkA", "#A0A0FF"), Colors.black); | |||
| Colors.spect_trB = disp->alloc_color (xrm->get (".color.spect.trB", "blue"), Colors.black); | |||
| Colors.spect_pkB = disp->alloc_color (xrm->get (".color.spect.pkB", "#A0A0FF"), Colors.black); | |||
| Colors.spect_trM = disp->alloc_color (xrm->get (".color.spect.trM", "darkgreen"), Colors.white); | |||
| Colors.butt_bg0 = disp->alloc_color (xrm->get (".color.butt.bg0", "#d0c8c0"), Colors.white); | |||
| Colors.butt_bg1 = disp->alloc_color (xrm->get (".color.butt.bg1", "yellow"), Colors.white); | |||
| Colors.butt_bg2 = disp->alloc_color (xrm->get (".color.butt.bg2", "green"), Colors.white); | |||
| Colors.butt_bgA = disp->alloc_color (xrm->get (".color.butt.bgA", "red"), Colors.black); | |||
| Colors.butt_bgB = disp->alloc_color (xrm->get (".color.butt.bgB", "blue"), Colors.black); | |||
| Colors.butt_bgM = disp->alloc_color (xrm->get (".color.butt.bgM", "green"), Colors.white); | |||
| XftColors.white = disp->alloc_xftcolor ("white", 0); | |||
| XftColors.black = disp->alloc_xftcolor ("black", 0); | |||
| XftColors.main_fg = disp->alloc_xftcolor (xrm->get (".color.main.fg", "black"), XftColors.black); | |||
| XftColors.text_fg = disp->alloc_xftcolor (xrm->get (".color.text.fg", "black"), XftColors.black); | |||
| XftColors.spect_fg = disp->alloc_xftcolor (xrm->get (".color.spect.fg", "blue"), XftColors.black); | |||
| XftColors.spect_sc = disp->alloc_xftcolor (xrm->get (".color.spect.sc", "black"), XftColors.black); | |||
| XftColors.spect_an = disp->alloc_xftcolor (xrm->get (".color.spect.an", "red"), XftColors.black); | |||
| XftColors.butt_fg0 = disp->alloc_xftcolor (xrm->get (".color.butt.fg0", "black"), XftColors.black); | |||
| XftColors.butt_fg1 = disp->alloc_xftcolor (xrm->get (".color.butt.fg1", "black"), XftColors.black); | |||
| XftColors.butt_fg2 = disp->alloc_xftcolor (xrm->get (".color.butt.fg2", "black"), XftColors.black); | |||
| XftColors.butt_fgA = disp->alloc_xftcolor (xrm->get (".color.butt.fgA", "white"), XftColors.white); | |||
| XftColors.butt_fgB = disp->alloc_xftcolor (xrm->get (".color.butt.fgB", "white"), XftColors.white); | |||
| XftColors.butt_fgM = disp->alloc_xftcolor (xrm->get (".color.butt.fgM", "black"), XftColors.black); | |||
| XftFonts.about1 = disp->alloc_xftfont (xrm->get (".font.about1", "times:pixelsize=24")); | |||
| XftFonts.about2 = disp->alloc_xftfont (xrm->get (".font.about2", "times:pixelsize=14")); | |||
| XftFonts.button = disp->alloc_xftfont (xrm->get (".font.button", "luxi:pixelsize=11")); | |||
| XftFonts.labels = disp->alloc_xftfont (xrm->get (".font.labels", "luxi:pixelsize=11")); | |||
| XftFonts.scales = disp->alloc_xftfont (xrm->get (".font.scales", "luxi:pixelsize=10")); | |||
| Bst0.font = XftFonts.button; | |||
| Bst0.color.bg [0] = Colors.butt_bg0; | |||
| Bst0.color.fg [0] = XftColors.butt_fg0; | |||
| Bst0.color.bg [1] = Colors.butt_bg1; | |||
| Bst0.color.fg [1] = XftColors.butt_fg1; | |||
| Bst0.color.bg [2] = Colors.butt_bg2; | |||
| Bst0.color.fg [2] = XftColors.butt_fg2; | |||
| Bst0.color.shadow.bgnd = Colors.main_bg; | |||
| Bst0.color.shadow.lite = Colors.main_ls; | |||
| Bst0.color.shadow.dark = Colors.main_ds; | |||
| Bst0.size.x = 17; | |||
| Bst0.size.y = 17; | |||
| Bst0.type = X_button_style::RAISED; | |||
| Bst1.font = XftFonts.button; | |||
| Bst1.color.bg [0] = Colors.butt_bg0; | |||
| Bst1.color.fg [0] = XftColors.butt_fg0; | |||
| Bst1.color.bg [1] = Colors.butt_bg1; | |||
| Bst1.color.fg [1] = XftColors.butt_fg1; | |||
| Bst1.color.bg [2] = Colors.butt_bg2; | |||
| Bst1.color.fg [2] = XftColors.butt_fg2; | |||
| Bst1.color.shadow.bgnd = Colors.main_bg; | |||
| Bst1.color.shadow.lite = Colors.main_ls; | |||
| Bst1.color.shadow.dark = Colors.main_ds; | |||
| Bst1.size.x = 17; | |||
| Bst1.size.y = 17; | |||
| Bst1.type = X_button_style::RAISED;// | X_button_style::LED; | |||
| BstA = Bst0; | |||
| BstA.color.bg [1] = Colors.butt_bgA; | |||
| BstA.color.fg [1] = XftColors.butt_fgA; | |||
| BstB = Bst0; | |||
| BstB.color.bg [1] = Colors.butt_bgB; | |||
| BstB.color.fg [1] = XftColors.butt_fgB; | |||
| BstM = Bst0; | |||
| BstM.color.bg [1] = Colors.butt_bgM; | |||
| BstM.color.fg [1] = XftColors.butt_fgM; | |||
| Tst0.font = XftFonts.labels; | |||
| Tst0.color.normal.bgnd = Colors.white; | |||
| Tst0.color.normal.text = XftColors.text_fg; | |||
| Tst0.color.shadow.lite = Colors.main_ls; | |||
| Tst0.color.shadow.dark = Colors.main_ds; | |||
| Tst0.color.shadow.bgnd = Colors.main_bg; | |||
| Tst1.font = XftFonts.labels; | |||
| Tst1.color.normal.bgnd = Colors.main_bg; | |||
| Tst1.color.normal.text = XftColors.main_fg; | |||
| Tst1.color.focus.bgnd = Colors.text_ed; | |||
| Tst1.color.focus.text = XftColors.main_fg; | |||
| Tst1.color.focus.line = Colors.text_ca; | |||
| Tst1.color.shadow.lite = Colors.main_ls; | |||
| Tst1.color.shadow.dark = Colors.main_ds; | |||
| Tst1.color.shadow.bgnd = Colors.main_bg; | |||
| } | |||
| @@ -0,0 +1,103 @@ | |||
| // ------------------------------------------------------------------------- | |||
| // | |||
| // Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org> | |||
| // | |||
| // This program 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 2 of the License, or | |||
| // (at your option) any later version. | |||
| // | |||
| // 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., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| // | |||
| // ------------------------------------------------------------------------- | |||
| #ifndef __STYLES_H | |||
| #define __STYLES_H | |||
| #include <clxclient.h> | |||
| struct colors | |||
| { | |||
| unsigned long white; | |||
| unsigned long black; | |||
| unsigned long main_bg; | |||
| unsigned long main_ds; | |||
| unsigned long main_ls; | |||
| unsigned long text_ed; | |||
| unsigned long text_ca; | |||
| unsigned long spect_bg; | |||
| unsigned long spect_gr; | |||
| unsigned long spect_mk; | |||
| unsigned long spect_trA; | |||
| unsigned long spect_pkA; | |||
| unsigned long spect_trB; | |||
| unsigned long spect_pkB; | |||
| unsigned long spect_trM; | |||
| unsigned long butt_bg0; | |||
| unsigned long butt_bg1; | |||
| unsigned long butt_bg2; | |||
| unsigned long butt_bgA; | |||
| unsigned long butt_bgB; | |||
| unsigned long butt_bgM; | |||
| }; | |||
| struct fonts | |||
| { | |||
| }; | |||
| struct xft_colors | |||
| { | |||
| XftColor *white; | |||
| XftColor *black; | |||
| XftColor *main_fg; | |||
| XftColor *text_fg; | |||
| XftColor *spect_fg; | |||
| XftColor *spect_sc; | |||
| XftColor *spect_an; | |||
| XftColor *butt_fg0; | |||
| XftColor *butt_fg1; | |||
| XftColor *butt_fg2; | |||
| XftColor *butt_fgA; | |||
| XftColor *butt_fgB; | |||
| XftColor *butt_fgM; | |||
| }; | |||
| struct xft_fonts | |||
| { | |||
| XftFont *about1; | |||
| XftFont *about2; | |||
| XftFont *button; | |||
| XftFont *labels; | |||
| XftFont *scales; | |||
| }; | |||
| extern struct colors Colors; | |||
| extern struct fonts Fonts; | |||
| extern struct xft_colors XftColors; | |||
| extern struct xft_fonts XftFonts; | |||
| extern X_button_style Bst0, Bst1, BstA, BstB, BstM; | |||
| extern X_textln_style Tst0, Tst1; | |||
| extern void init_styles (X_display *disp, X_resman *xrm); | |||
| #define PROGNAME "Jack/Alsa Audio Analyser" | |||
| #endif | |||