Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] python bindings #1303

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b76c6d1
Proof of concept PySide bindings
charbeljc Jun 16, 2021
4502ee2
H2Core::Sample instanciable from python!
charbeljc Jun 17, 2021
0c616be
add Sample::set_filepath(), fix Sample::is_empty()
charbeljc Jun 17, 2021
e46f5a2
mostly testable
charbeljc Jun 18, 2021
dbc18c6
missing enums
charbeljc Jun 18, 2021
31737fe
playing with shiboken
charbeljc Jun 18, 2021
ce78fa8
build gui as a library
charbeljc Jun 18, 2021
28220cf
prepare to build more than one bindings
charbeljc Jun 18, 2021
a632b25
start gui library bindings
charbeljc Jun 19, 2021
b977937
reorg, module h2gui.so builds
charbeljc Jun 19, 2021
9d0c2db
silent undefined method declarations
charbeljc Jun 19, 2021
a4c1897
TargetWaveDisplay: avoid crash if no HydrogenApp instance
charbeljc Jun 19, 2021
f520050
update bindings
charbeljc Jun 19, 2021
8d44c68
fix linkage problems
charbeljc Jun 19, 2021
cbf7835
more widget bindings
charbeljc Jun 19, 2021
af2ee27
more bindings (QtDesigner .ui widgets)
charbeljc Jun 19, 2021
4c71749
some crash proofing from python bindings
charbeljc Jun 19, 2021
ccf838f
more cleanups
charbeljc Jun 19, 2021
664706f
get actual samples
charbeljc Jun 20, 2021
4402a3f
binding more widgets
charbeljc Jun 21, 2021
d87b4a6
decoupling instrument editor from hydrogen singleton
charbeljc Jun 21, 2021
8aed77a
Ok, shiboken is good for Qt framework, useless for anything else
charbeljc Jun 21, 2021
803444c
enter pybind11
charbeljc Jun 22, 2021
7263a67
binding config mostly omplete
charbeljc Jun 23, 2021
8401740
core adjustments
charbeljc Jun 23, 2021
e1850cd
gui adjustments
charbeljc Jun 23, 2021
e9a0a7f
add generated bindings
charbeljc Jun 23, 2021
5638196
build core bindings with pybind11, gui bindings with shiboken
charbeljc Jun 23, 2021
85daea6
start making instrument editor standalone
charbeljc Jun 23, 2021
d7346cb
update examples
charbeljc Jun 23, 2021
6581837
disable python bindings by default
charbeljc Jun 23, 2021
ccd2e97
rework example
charbeljc Jun 23, 2021
20277cd
fix windows build
charbeljc Jun 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ ENDIF()

OPTION(WANT_CPPUNIT "Include CppUnit test suite" ON)
OPTION(FIXME_DISABLE_OPTIMIZATIONS "Fix broken builds by turning off optimizations" OFF)
OPTION(WANT_PYSIDE "Build PySide bindings for h2core library" OFF)
OPTION(WANT_PYBIND11 "Build PyBind11 bindings for h2core library" OFF)

include(Sanitizers)
INCLUDE(StatusSupportOptions)
Expand Down Expand Up @@ -316,7 +318,9 @@ COLOR_MESSAGE("${cyan}Installation Summary${reset}
* core library build as : ${H2CORE_LIBRARY_TYPE}
* debug capabilities : ${H2CORE_HAVE_DEBUG}
* macosx bundle : ${H2CORE_HAVE_BUNDLE}
* fat build : ${WANT_FAT_BUILD}\n"
* fat build : ${WANT_FAT_BUILD}
* PySide bindings : ${WANT_PYSIDE}
* Pybind11 bindings : ${WANT_PYBIND11}\n"
)

COLOR_MESSAGE("${cyan}Main librarires${reset}")
Expand Down Expand Up @@ -397,6 +401,14 @@ ADD_SUBDIRECTORY(data/i18n)
ADD_SUBDIRECTORY(src/cli)
ADD_SUBDIRECTORY(src/player)
ADD_SUBDIRECTORY(src/gui)
IF (WANT_PYSIDE)
message("${purple}PySide!!!!\n")
ADD_SUBDIRECTORY(src/shiboken_bindings)
ENDIF()
IF (WANT_PYBIND11)
message("${green}Pybind11!!")
ADD_SUBDIRECTORY(src/pybind11_bindings)
ENDIF()
IF(EXISTS ${CMAKE_SOURCE_DIR}/data/doc/CMakeLists.txt)
ADD_SUBDIRECTORY(data/doc)
ENDIF()
Expand Down
32 changes: 26 additions & 6 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

QTDIR=${QTDIR:-/usr/lib/qt}
VERBOSE=${VERBOSE:-0}
CMAKE_OPTIONS="
USE_NINJA=${USE_NINJA:-0}
WANT_PYSIDE=${WANT_PYSIDE:-0}
WANT_PYBIND11=${WANT_PYBIND11:-0}
CMAKE_OPTIONS="\
-DCMAKE_COLOR_MAKEFILE=1 \
-DWANT_DEBUG=1 \
-DWANT_JACK=1 \
Expand All @@ -17,7 +20,16 @@ CMAKE_OPTIONS="
-DWANT_COREAUDIO=1 \
-DWANT_COREMIDI=1
"
MAKE_OPTS="-j 3"
if [ ${WANT_PYSIDE} -ne 0 ]; then
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DWANT_PYSIDE=TRUE"
fi
if [ ${WANT_PYBIND11} -ne 0 ]; then
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DWANT_PYBIND11=TRUE"
fi
if [ ${USE_NINJA} -ne 0 ]; then
CMAKE_OPTIONS="${CMAKE_OPTIONS} -G Ninja"
fi
MAKE_OPTS="-j 12"
H2FLAGS="-V0xf"
BUILD_DIR=./build

Expand Down Expand Up @@ -50,11 +62,19 @@ function cmake_make() {
cmake_init
echo -e " * cmake make\n" && cd $BUILD_DIR || exit 1
if [ $VERBOSE -eq 1 ]; then
VERBOSE=1 make translations $MAKE_OPTS || exit 1
VERBOSE=1 make $MAKE_OPTS || exit 1
if [ $USE_NINJA -ne 0 ]; then
VERBOSE=1 ninja $MAKE_OPTS || exit 1
else
VERBOSE=1 make translations $MAKE_OPTS || exit 1
VERBOSE=1 make $MAKE_OPTS || exit 1
fi
else
make translations $MAKE_OPTS || exit 1
make $MAKE_OPTS || exit 1
if [ $USE_NINJA -ne 0 ]; then
ninja $MAKE_OPTS || exit 1
else
make translations $MAKE_OPTS || exit 1
make $MAKE_OPTS || exit 1
fi
fi

if [[ "$PLATFORM_STR" == 'Linux' ]]; then
Expand Down
8 changes: 6 additions & 2 deletions src/core/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
*
*/

#include <core/AudioEngine.h>

#ifdef WIN32
# include "core/Timehelper.h"
#else
# include <unistd.h>
# include <sys/time.h>
#endif

#include <core/config.h>
#include <core/AudioEngine.h>
#include <core/EventQueue.h>
#include <core/FX/Effects.h>
#include <core/Basics/Song.h>
Expand Down Expand Up @@ -58,7 +58,9 @@
#include <core/IO/AlsaMidiDriver.h>
#include <core/IO/JackMidiDriver.h>
#include <core/IO/PortMidiDriver.h>
#ifdef H2CORE_HAVE_COREAUDIO
#include <core/IO/CoreAudioDriver.h>
#endif
#include <core/IO/PulseAudioDriver.h>

#include <core/Hydrogen.h> // TODO: remove this line as soon as possible
Expand Down Expand Up @@ -537,6 +539,7 @@ AudioOutput* AudioEngine::createDriver( const QString& sDriver )
}
}
//#ifdef Q_OS_MACX
#ifdef H2CORE_HAVE_COREAUDIO
else if ( sDriver == "CoreAudio" ) {
___INFOLOG( "Creating CoreAudioDriver" );
pDriver = new CoreAudioDriver( m_AudioProcessCallback );
Expand All @@ -545,6 +548,7 @@ AudioOutput* AudioEngine::createDriver( const QString& sDriver )
pDriver = nullptr;
}
}
#endif
//#endif
else if ( sDriver == "PulseAudio" ) {
pDriver = new PulseAudioDriver( m_AudioProcessCallback );
Expand Down
5 changes: 4 additions & 1 deletion src/core/AudioEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,9 @@ class AudioEngine : public H2Core::Object
* #STATE_PLAYING the function will immediately return.
*/
inline void processTransport();

#if 0
inline unsigned renderNote( Note* pNote, const unsigned& nBufferSize );
#endif
// TODO: Add documentation of inPunchArea, and
// m_addMidiNoteVector
/**
Expand Down Expand Up @@ -438,7 +439,9 @@ class AudioEngine : public H2Core::Object
* cycle.
*/
int updateNoteQueue( unsigned nFrames );
#if 0
void prepNoteQueue();
#endif

/**
* Find a PatternList corresponding to the supplied tick position @a
Expand Down
1 change: 1 addition & 0 deletions src/core/Basics/Playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define H2C_PLAYLIST_H

#include <core/Object.h>
#include <core/Helpers/Xml.h>

namespace H2Core
{
Expand Down
56 changes: 34 additions & 22 deletions src/core/Basics/Sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,39 @@ namespace H2Core
{

const char* Sample::__class_name = "Sample";
const char* EnvelopePoint::__class_name = "EnvolopePoint";

const char* EnvelopePoint::__class_name = "EnvelopePoint";
const std::vector<QString> Sample::__loop_modes = { "forward", "reverse", "pingpong" };

#if defined(H2CORE_HAVE_RUBBERBAND) || _DOXYGEN_
static double compute_pitch_scale( const Sample::Rubberband& r );
static RubberBand::RubberBandStretcher::Options compute_rubberband_options( const Sample::Rubberband& r );
#endif


/* EnvelopePoint */
EnvelopePoint::EnvelopePoint() : Object( EnvelopePoint::__class_name ), frame( 0 ), value( 0 )
EnvelopePoint::EnvelopePoint()
{
frame = value = 0;
}
EnvelopePoint::EnvelopePoint(int f, int v)
{
frame = f;
value = v;
}

EnvelopePoint::EnvelopePoint( int f, int v ) : Object( EnvelopePoint::__class_name ), frame( f ), value( v )
EnvelopePoint::EnvelopePoint(const EnvelopePoint & other )
{
frame = other.frame;
value = other.value;
}

EnvelopePoint::EnvelopePoint( EnvelopePoint* other ) : Object( EnvelopePoint::__class_name )
Sample::Sample() : Object( Sample::__class_name ),
__filepath( "" ),
__frames( 0 ),
__sample_rate( 0 ),
__data_l( nullptr ),
__data_r( nullptr ),
__is_modified( false )
{
frame = other->frame;
value = other->value;
}
/* EnvelopePoint */


Sample::Sample( const QString& filepath, int frames, int sample_rate, float* data_l, float* data_r ) : Object( Sample::__class_name ),
Expand Down Expand Up @@ -101,12 +109,12 @@ Sample::Sample( std::shared_ptr<Sample> pOther ): Object( __class_name ),

PanEnvelope* pPan = pOther->get_pan_envelope();
for( int i=0; i<pPan->size(); i++ ) {
__pan_envelope.push_back( std::make_unique<EnvelopePoint>( pPan->at(i).get() ) );
__pan_envelope.push_back( pPan->at(i) );
}

PanEnvelope* pVelocity = pOther->get_velocity_envelope();
for( int i=0; i<pVelocity->size(); i++ ) {
__velocity_envelope.push_back( std::make_unique<EnvelopePoint>( pVelocity->at(i).get() ) );
__velocity_envelope.push_back( pVelocity->at(i) );
}
}

Expand All @@ -127,6 +135,10 @@ void Sample::set_filename( const QString& filename )
__filepath = QDir(Dest.absolutePath()).filePath( Filename.fileName() );
}

void Sample::set_filepath( const QString& filepath)
{
__filepath = filepath;
}

std::shared_ptr<Sample> Sample::load( const QString& sFilepath )
{
Expand Down Expand Up @@ -355,10 +367,10 @@ void Sample::apply_velocity( const VelocityEnvelope& v )
if ( v.size() > 0 ) {
float inv_resolution = __frames / 841.0F;
for ( int i = 1; i < v.size(); i++ ) {
float y = ( 91 - v[i - 1]->value ) / 91.0F;
float k = ( 91 - v[i]->value ) / 91.0F;
int start_frame = v[i - 1]->frame * inv_resolution;
int end_frame = v[i]->frame * inv_resolution;
float y = ( 91 - v[i - 1].value ) / 91.0F;
float k = ( 91 - v[i].value ) / 91.0F;
int start_frame = v[i - 1].frame * inv_resolution;
int end_frame = v[i].frame * inv_resolution;
if ( i == v.size() -1 ) {
end_frame = __frames;
}
Expand All @@ -372,7 +384,7 @@ void Sample::apply_velocity( const VelocityEnvelope& v )
}

for(auto& pEnvPtr : v){
__velocity_envelope.emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
__velocity_envelope.emplace_back( pEnvPtr );
}
}
__is_modified = true;
Expand All @@ -390,10 +402,10 @@ void Sample::apply_pan( const PanEnvelope& p )
if ( p.size() > 0 ) {
float inv_resolution = __frames / 841.0F;
for ( int i = 1; i < p.size(); i++ ) {
float y = ( 45 - p[i - 1]->value ) / 45.0F;
float k = ( 45 - p[i]->value ) / 45.0F;
int start_frame = p[i - 1]->frame * inv_resolution;
int end_frame = p[i]->frame * inv_resolution;
float y = ( 45 - p[i - 1].value ) / 45.0F;
float k = ( 45 - p[i].value ) / 45.0F;
int start_frame = p[i - 1].frame * inv_resolution;
int end_frame = p[i].frame * inv_resolution;
if ( i == p.size() -1 ) {
end_frame = __frames;
}
Expand All @@ -418,7 +430,7 @@ void Sample::apply_pan( const PanEnvelope& p )
}

for(auto& pEnvPtr : p){
__pan_envelope.emplace_back( std::make_unique<EnvelopePoint>( pEnvPtr.get() ) );
__pan_envelope.emplace_back( pEnvPtr );
}
}
__is_modified = true;
Expand Down
37 changes: 22 additions & 15 deletions src/core/Basics/Sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#ifndef H2C_SAMPLE_H
#define H2C_SAMPLE_H

#include <memory>
// #include <memory>
#include <vector>
#include <sndfile.h>

Expand All @@ -37,29 +37,31 @@ namespace H2Core
*/

/** an envelope point within a frame */
class EnvelopePoint : public H2Core::Object
class EnvelopePoint // : public H2Core::Object
{
H2_OBJECT
// H2_OBJECT
public:
int frame; ///< frame index
int value; ///< value
/** to be able to sort velocity points vectors */
struct Comparator {
bool operator()( std::unique_ptr<EnvelopePoint>& a, std::unique_ptr<EnvelopePoint>& b )
bool operator()( const EnvelopePoint& a, const EnvelopePoint& b )
{
return a->frame < b->frame;
return a.frame < b.frame;
}
};
/** default constructor */
// /** default constructor */
EnvelopePoint();
/**
* constructor
* \param f the frame index
* \param v the value associated with the frame
*/
EnvelopePoint(const EnvelopePoint&);
// /**
// * constructor
// * \param f the frame index
// * \param v the value associated with the frame
// */
EnvelopePoint( int f, int v );
/** copy constructor */
EnvelopePoint( EnvelopePoint* other );
private:
static const char *__class_name;
};

class Sample : public H2Core::Object
Expand All @@ -68,9 +70,9 @@ class Sample : public H2Core::Object
public:

/** define the type used to store pan envelope points */
using PanEnvelope = std::vector<std::unique_ptr<EnvelopePoint>>;
using PanEnvelope = std::vector<EnvelopePoint>;
/** define the type used to store velocity envelope points */
using VelocityEnvelope = std::vector<std::unique_ptr<EnvelopePoint>>;
using VelocityEnvelope = std::vector<EnvelopePoint>;
/** set of loop configuration flags */
class Loops
{
Expand Down Expand Up @@ -126,6 +128,7 @@ class Sample : public H2Core::Object
}
QString toQString( const QString& sPrefix, bool bShort ) const;
};
Sample();

/**
* Sample constructor
Expand All @@ -135,6 +138,7 @@ class Sample : public H2Core::Object
* \param data_l the left channel array of data
* \param data_r the right channel array of data
*/

Sample( const QString& filepath, int frames=0, int sample_rate=0, float* data_l=nullptr, float* data_r=nullptr );
/** copy constructor */
Sample( std::shared_ptr<Sample> other );
Expand Down Expand Up @@ -212,6 +216,7 @@ class Sample : public H2Core::Object
*
* \fn load()
*/

bool load();
/**
* Flush the current content of the left and right
Expand Down Expand Up @@ -271,6 +276,8 @@ class Sample : public H2Core::Object
const QString get_filepath() const;
/** \return Filename part of #__filepath */
const QString get_filename() const;
/** \param filepath the file to load audio data from*/
void set_filepath( const QString& filepath );
/** \param filename Filename part of #__filepath*/
void set_filename( const QString& filename );
/**
Expand Down Expand Up @@ -363,7 +370,7 @@ inline void Sample::unload()

inline bool Sample::is_empty() const
{
return ( __data_l==__data_r==0 );
return ( __data_l==nullptr && __data_r==nullptr );
}

inline const QString Sample::get_filepath() const
Expand Down
Loading