f@1: /*
f@1:
f@5: Copyright (C) 2016 Queen Mary University of London
f@5: Author: Fiore Martin
f@1:
f@5: This file is part of Collidoscope.
f@5:
f@5: Collidoscope is free software: you can redistribute it and/or modify
f@5: it under the terms of the GNU General Public License as published by
f@5: the Free Software Foundation, either version 3 of the License, or
f@5: (at your option) any later version.
f@5:
f@5: This program is distributed in the hope that it will be useful,
f@5: but WITHOUT ANY WARRANTY; without even the implied warranty of
f@5: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@5: GNU General Public License for more details.
f@5:
f@5: You should have received a copy of the GNU General Public License
f@5: along with this program. If not, see .
f@5:
f@5: This file incorporates work covered by the following copyright and permission notice:
f@5:
f@5: Copyright (c) 2014, The Cinder Project
f@5:
f@5: This code is intended to be used with the Cinder C++ library, http://libcinder.org
f@5:
f@5: Redistribution and use in source and binary forms, with or without modification, are permitted provided that
f@5: the following conditions are met:
f@1:
f@1: * Redistributions of source code must retain the above copyright notice, this list of conditions and
f@5: the following disclaimer.
f@1: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
f@5: the following disclaimer in the documentation and/or other materials provided with the distribution.
f@1:
f@5: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
f@5: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
f@5: PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
f@5: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
f@5: TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
f@5: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
f@5: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
f@5: POSSIBILITY OF SUCH DAMAGE.
f@5:
f@1: */
f@1:
f@1: #pragma once
f@1:
f@1: #include "cinder/audio/Context.h"
f@1: #include
f@1:
f@1: namespace cinder { namespace audio { namespace linux {
f@1:
f@1: class ContextJack;
f@1: class InputDeviceNodeJack;
f@1:
f@4: /**
f@4: * OutputNode (as in the cinder::audio::OutputNode) that sends audio to the sound card using the jack audio callback method.
f@4: */
f@1: class OutputDeviceNodeJack : public OutputDeviceNode {
f@1: public:
f@5: OutputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr &context );
f@1:
f@4: /** Gives this output node a reference to the JackInputNode.
f@4: * In initialize() the reference is used to give the input node access to jack input ports
f@4: */
f@1: void setInput(InputDeviceNodeRef inputDeviceNode);
f@1:
f@1: protected:
f@5: void initialize() override;
f@5: void uninitialize() override;
f@5: void enableProcessing() override;
f@5: void disableProcessing() override;
f@5: bool supportsProcessInPlace() const override { return false; }
f@1:
f@1: private:
f@4: // this is called by jack in the audio thread at every tick of the sound card
f@1: static int jackCallback(jack_nframes_t nframes, void* userData);
f@1:
f@1:
f@5: void renderToBufferFromInputs();
f@1:
f@4: /**
f@4: * RenderData is passed as user_data to jack when the jack process callback is installed
f@4: */
f@1: struct RenderData{
f@1: RenderData() : inputNode(nullptr), outputNode(nullptr), context(nullptr){}
f@1: ~RenderData() { inputNode = nullptr; outputNode = nullptr; context = nullptr; }
f@1: Node* outputNode;
f@1: Node* inputNode;
f@1: ContextJack* context;
f@1: } mRenderData;
f@1:
f@1: std::weak_ptr mCinderContext;
f@1:
f@5: jack_client_t *mClient;
f@1:
f@1: std::array< jack_port_t*, 2 > mOutputPorts;
f@1:
f@1: std::shared_ptr mInputDeviceNode;
f@1: };
f@1:
f@4: /**
f@4: * InputNode (as in the cinder::audio::OutputNode) that reads audio from the sound card using the jack audio callback method.
f@4: */
f@1: class InputDeviceNodeJack : public InputDeviceNode {
f@1: friend OutputDeviceNodeJack;
f@1:
f@1: public:
f@5: InputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr &context );
f@1:
f@1: protected:
f@5: void initialize() override;
f@5: void uninitialize() override;
f@5: void enableProcessing() override;
f@5: void disableProcessing() override;
f@5: void process( Buffer *buffer ) override;
f@1:
f@1: private:
f@1: std::array< jack_port_t*, 2 > mInputPorts;
f@1: };
f@1:
f@1: class ContextJack : public Context {
f@1: public:
f@5: ContextJack() {}
f@5: virtual ~ContextJack() {}
f@1:
f@1:
f@5: OutputDeviceNodeRef createOutputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format() ) override;
f@5: InputDeviceNodeRef createInputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format() ) override;
f@1:
f@5: OutputDeviceNodeRef mOutputDeviceNode;
f@5: InputDeviceNodeRef mInputDeviceNode;
f@1:
f@1:
f@1: private:
f@5: };
f@1:
f@1: } } } // namespace cinder::audio::linux
f@4: