| Atom.hpp | | Atom.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_ATOM_HPP | | #ifndef RAUL_ATOM_HPP | |
| #define RAUL_ATOM_HPP | | #define RAUL_ATOM_HPP | |
| | | | |
|
| | | #include <stdint.h> | |
| #include <cstdlib> | | #include <cstdlib> | |
| #include <cassert> | | #include <cassert> | |
| #include <cstring> | | #include <cstring> | |
| #include <string> | | #include <string> | |
| #include <sstream> | | #include <sstream> | |
| #include <iostream> | | #include <iostream> | |
| | | | |
|
| //#include CONFIG_H_PATH | | | |
| | | | |
| #define CUC(x) ((const unsigned char*)(x)) | | #define CUC(x) ((const unsigned char*)(x)) | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
|
| /** An OSC atom (fundamental data types OSC messages are composed of). | | /** A piece of data with some type. | |
| | | * | |
| | | * Atoms can be of various primitive types (integer, float, etc) as well as | |
| | | * a string or primitive. The primitive types are entirely contained withi | |
| | | n | |
| | | * the Atom, i.e. the Atom is POD. String, URI, and blob atoms are not POD | |
| | | . | |
| * | | * | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
| class Atom { | | class Atom { | |
| public: | | public: | |
|
| | | | |
| enum Type { | | enum Type { | |
| NIL, | | NIL, | |
| INT, | | INT, | |
| FLOAT, | | FLOAT, | |
| BOOL, | | BOOL, | |
|
| | | URI, | |
| STRING, | | STRING, | |
| BLOB | | BLOB | |
| }; | | }; | |
| | | | |
|
| Atom() : _type(NIL), _blob_val(0) | | Atom() : _type(NIL), _blob_val(0) {} | |
| {} | | Atom(int32_t val) : _type(INT), _int_val(val) {} | |
| Atom(int32_t val) : _type(INT), _int_val(val) | | Atom(float val) : _type(FLOAT), _float_val(val) {} | |
| {} | | Atom(bool val) : _type(BOOL), _bool_val(val) {} | |
| Atom(float val) : _type(FLOAT), _float_val(val) | | Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {} | |
| {} | | | |
| Atom(bool val) : _type(BOOL), _bool_val(val) | | | |
| {} | | | |
| Atom(const char* val) : _type(STRING), _string_val(strdup(val | | | |
| )) {} | | | |
| Atom(const std::string& val) : _type(STRING), _string_val(strdup(val | | | |
| .c_str())) {} | | | |
| | | | |
|
| Atom(void* val) : _type(BLOB), _blob_size(sizeof(val)), _blob_val(ma | | Atom(Type t, const std::string& val) : _type(t), _string_val(strdup( | |
| lloc(_blob_size)) | | val.c_str())) {} | |
| { memcpy(_blob_val, val, sizeof(_blob_size)); } | | | |
| | | Atom(const char* type_uri, size_t size, void* val) : _type(BLOB) { | |
| | | _blob_type_length = strlen(type_uri) + 1; // + 1 for \0 | |
| | | _blob_size = size; | |
| | | _blob_val = malloc(_blob_type_length + _blob_size); | |
| | | memcpy(_blob_val, type_uri, _blob_type_length); | |
| | | memcpy((char*)_blob_val + _blob_type_length, val, size); | |
| | | } | |
| | | | |
| ~Atom() { | | ~Atom() { | |
|
| if (_type == STRING) | | if (_type == URI || _type == STRING) | |
| free(_string_val); | | free(_string_val); | |
| else if (_type == BLOB) | | else if (_type == BLOB) | |
| free(_blob_val); | | free(_blob_val); | |
| } | | } | |
| | | | |
|
| // Gotta love C++ boilerplate: | | | |
| | | | |
| Atom(const Atom& copy) | | Atom(const Atom& copy) | |
| : _type(copy._type) | | : _type(copy._type) | |
|
| , _blob_size(copy._blob_size) | | | |
| { | | { | |
| switch (_type) { | | switch (_type) { | |
| case NIL: _blob_val = 0; break; | | case NIL: _blob_val = 0; break; | |
| case INT: _int_val = copy._int_val; break; | | case INT: _int_val = copy._int_val; break; | |
| case FLOAT: _float_val = copy._float_val; break; | | case FLOAT: _float_val = copy._float_val; break; | |
| case BOOL: _bool_val = copy._bool_val; break; | | case BOOL: _bool_val = copy._bool_val; break; | |
|
| | | case URI: | |
| case STRING: _string_val = strdup(copy._string_val); break; | | case STRING: _string_val = strdup(copy._string_val); break; | |
|
| | | case BLOB: _blob_size = copy._blob_size; | |
| case BLOB: _blob_val = malloc(_blob_size); | | _blob_type_length = copy._blob_type_length; | |
| memcpy(_blob_val, copy._blob_val, _blob_size); | | _blob_val = malloc(_blob_type_length + _blob_si | |
| | | ze); | |
| | | memcpy(_blob_val, copy._blob_val, _blob_type_le | |
| | | ngth + _blob_size); | |
| break; | | break; | |
|
| | | | |
| default: break; | | | |
| } | | } | |
| } | | } | |
| | | | |
| Atom& operator=(const Atom& other) { | | Atom& operator=(const Atom& other) { | |
| if (_type == BLOB) | | if (_type == BLOB) | |
| free(_blob_val); | | free(_blob_val); | |
| else if (_type == STRING) | | else if (_type == STRING) | |
| free(_string_val); | | free(_string_val); | |
| | | | |
| _type = other._type; | | _type = other._type; | |
|
| _blob_size = other._blob_size; | | | |
| | | | |
| switch (_type) { | | switch (_type) { | |
| case NIL: _blob_val = 0; break; | | case NIL: _blob_val = 0; break; | |
| case INT: _int_val = other._int_val; break; | | case INT: _int_val = other._int_val; break; | |
| case FLOAT: _float_val = other._float_val; break; | | case FLOAT: _float_val = other._float_val; break; | |
| case BOOL: _bool_val = other._bool_val; break; | | case BOOL: _bool_val = other._bool_val; break; | |
|
| | | case URI: | |
| case STRING: _string_val = strdup(other._string_val); break; | | case STRING: _string_val = strdup(other._string_val); break; | |
|
| | | case BLOB: _blob_size = other._blob_size; | |
| case BLOB: _blob_val = malloc(_blob_size); | | _blob_type_length = other._blob_type_length; | |
| memcpy(_blob_val, other._blob_val, _blob_size); | | _blob_val = malloc(_blob_type_length + _blob_si | |
| | | ze); | |
| | | memcpy(_blob_val, other._blob_val, _blob_type_l | |
| | | ength + _blob_size); | |
| break; | | break; | |
|
| | | | |
| default: break; | | | |
| } | | } | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | inline bool operator==(const Atom& other) const { | |
| | | if (_type == other.type()) { | |
| | | switch (_type) { | |
| | | case NIL: return true; | |
| | | case INT: return _int_val == other._int_val; | |
| | | case FLOAT: return _float_val == other._float_val; | |
| | | case BOOL: return _bool_val == other._bool_val; | |
| | | case URI: | |
| | | case STRING: return strcmp(_string_val, other._strin | |
| | | g_val) == 0; | |
| | | case BLOB: return _blob_val == other._blob_val; | |
| | | } | |
| | | } | |
| | | return false; | |
| | | } | |
| | | | |
| | | inline bool operator!=(const Atom& other) const { return ! operator= | |
| | | =(other); } | |
| | | | |
| | | inline bool operator<(const Atom& other) const { | |
| | | if (_type == other.type()) { | |
| | | switch (_type) { | |
| | | case NIL: return true; | |
| | | case INT: return _int_val < other._int_val; | |
| | | case FLOAT: return _float_val < other._float_val; | |
| | | case BOOL: return _bool_val < other._bool_val; | |
| | | case URI: | |
| | | case STRING: return strcmp(_string_val, other._strin | |
| | | g_val) < 0; | |
| | | case BLOB: return _blob_val < other._blob_val; | |
| | | } | |
| | | } | |
| | | return _type < other.type(); | |
| | | } | |
| | | | |
| | | inline size_t data_size() const { | |
| | | switch (_type) { | |
| | | case NIL: return 0; | |
| | | case INT: return sizeof(uint32_t); | |
| | | case FLOAT: return sizeof(float); | |
| | | case BOOL: return sizeof(bool); | |
| | | case URI: | |
| | | case STRING: return strlen(_string_val); | |
| | | case BLOB: return _blob_size; | |
| | | } | |
| | | return 0; | |
| | | } | |
| | | | |
| | | inline bool is_valid() const { return (_type != NIL); } | |
| | | | |
| /** Type of this atom. Always check this before attempting to get t
he | | /** Type of this atom. Always check this before attempting to get t
he | |
| * value - attempting to get the incorrectly typed value is a fatal
error. | | * value - attempting to get the incorrectly typed value is a fatal
error. | |
| */ | | */ | |
| Type type() const { return _type; } | | Type type() const { return _type; } | |
| | | | |
| inline int32_t get_int32() const { assert(_type == INT); ret
urn _int_val; } | | inline int32_t get_int32() const { assert(_type == INT); ret
urn _int_val; } | |
| inline float get_float() const { assert(_type == FLOAT); ret
urn _float_val; } | | inline float get_float() const { assert(_type == FLOAT); ret
urn _float_val; } | |
| inline bool get_bool() const { assert(_type == BOOL); ret
urn _bool_val; } | | inline bool get_bool() const { assert(_type == BOOL); ret
urn _bool_val; } | |
| inline const char* get_string() const { assert(_type == STRING); ret
urn _string_val; } | | inline const char* get_string() const { assert(_type == STRING); ret
urn _string_val; } | |
|
| inline const void* get_blob() const { assert(_type == BLOB); ret
urn _blob_val; } | | inline const char* get_uri() const { assert(_type == URI); ret
urn _string_val; } | |
| | | | |
|
| inline operator bool() const { return (_type != NIL); } | | inline const char* get_blob_type() const { assert(_type == BLOB); re | |
| | | turn (const char*)_blob_val; } | |
| | | inline const void* get_blob() const { assert(_type == BLOB); re | |
| | | turn (const char*)_blob_val + _blob_type_length; } | |
| | | | |
| private: | | private: | |
| Type _type; | | Type _type; | |
| | | | |
|
| size_t _blob_size; ///< always a multiple of 32 | | | |
| | | | |
| union { | | union { | |
| int32_t _int_val; | | int32_t _int_val; | |
| float _float_val; | | float _float_val; | |
| bool _bool_val; | | bool _bool_val; | |
| char* _string_val; | | char* _string_val; | |
|
| void* _blob_val; | | struct { | |
| | | size_t _blob_type_length; // length of type string ( | |
| | | first part of buffer, inc. \0) | |
| | | size_t _blob_size; // length of data after ty | |
| | | pe string | |
| | | void* _blob_val; // buffer | |
| | | }; | |
| }; | | }; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
|
| | | static inline std::ostream& operator<<(std::ostream& os, const Raul::Atom& | |
| | | atom) | |
| | | { | |
| | | switch (atom.type()) { | |
| | | case Raul::Atom::NIL: return os << "(nil)"; | |
| | | case Raul::Atom::INT: return os << atom.get_int32(); | |
| | | case Raul::Atom::FLOAT: return os << atom.get_float(); | |
| | | case Raul::Atom::BOOL: return os << atom.get_bool(); | |
| | | case Raul::Atom::URI: return os << "<" << atom.get_uri() << ">"; | |
| | | case Raul::Atom::STRING: return os << atom.get_string(); | |
| | | case Raul::Atom::BLOB: return os << atom.get_blob(); | |
| | | } | |
| | | return os; | |
| | | } | |
| | | | |
| #endif // RAUL_ATOM_HPP | | #endif // RAUL_ATOM_HPP | |
| | | | |
End of changes. 24 change blocks. |
| 40 lines changed or deleted | | 117 lines changed or added | |
|
| AtomLiblo.hpp | | AtomLiblo.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_ATOM_LIBLO_HPP | | #ifndef RAUL_ATOM_LIBLO_HPP | |
| #define RAUL_ATOM_LIBLO_HPP | | #define RAUL_ATOM_LIBLO_HPP | |
| | | | |
|
| | | #include <iostream> | |
| #include <lo/lo.h> | | #include <lo/lo.h> | |
|
| #include <raul/Atom.hpp> | | #include "raul/Atom.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Conversion between Raul Atoms and Liblo OSC arguments. | | /** Conversion between Raul Atoms and Liblo OSC arguments. | |
| * This code (in header raul/AtomLiblo.hpp) depends on liblo, only apps whi
ch | | * This code (in header raul/AtomLiblo.hpp) depends on liblo, only apps whi
ch | |
| * directly depend on both raul and liblo should include it. | | * directly depend on both raul and liblo should include it. | |
| */ | | */ | |
| namespace AtomLiblo { | | namespace AtomLiblo { | |
| | | | |
| /** Append a Raul Atom as a parameter to a liblo message */ | | /** Append a Raul Atom as a parameter to a liblo message */ | |
| | | | |
| skipping to change at line 46 | | skipping to change at line 47 | |
| switch (atom.type()) { | | switch (atom.type()) { | |
| case Atom::INT: | | case Atom::INT: | |
| lo_message_add_int32(m, atom.get_int32()); | | lo_message_add_int32(m, atom.get_int32()); | |
| break; | | break; | |
| case Atom::FLOAT: | | case Atom::FLOAT: | |
| lo_message_add_float(m, atom.get_float()); | | lo_message_add_float(m, atom.get_float()); | |
| break; | | break; | |
| case Atom::STRING: | | case Atom::STRING: | |
| lo_message_add_string(m, atom.get_string()); | | lo_message_add_string(m, atom.get_string()); | |
| break; | | break; | |
|
| | | case Atom::URI: | |
| | | lo_message_add_symbol(m, atom.get_uri()); | |
| | | break; | |
| | | case Atom::BOOL: | |
| | | if (atom.get_bool()) | |
| | | lo_message_add_true(m); | |
| | | else | |
| | | lo_message_add_false(m); | |
| | | break; | |
| case Atom::BLOB: | | case Atom::BLOB: | |
|
| // FIXME: is this okay? what does liblo do? | | if (atom.data_size() > 0) | |
| lo_message_add_blob(m, const_cast<void*>(atom.get_blob())); | | lo_message_add_blob(m, lo_blob_new(atom.data_size(), | |
| | | atom.get_blob())); | |
| | | else | |
| | | lo_message_add_nil(m); | |
| break; | | break; | |
| case Atom::NIL: | | case Atom::NIL: | |
| default: | | default: | |
| lo_message_add_nil(m); | | lo_message_add_nil(m); | |
| break; | | break; | |
| } | | } | |
| } | | } | |
| | | | |
| /** Convert a liblo argument to a Raul::Atom */ | | /** Convert a liblo argument to a Raul::Atom */ | |
| inline Atom | | inline Atom | |
| lo_arg_to_atom(char type, lo_arg* arg) | | lo_arg_to_atom(char type, lo_arg* arg) | |
| { | | { | |
| switch (type) { | | switch (type) { | |
| case 'i': | | case 'i': | |
| return Atom(arg->i); | | return Atom(arg->i); | |
| case 'f': | | case 'f': | |
| return Atom(arg->f); | | return Atom(arg->f); | |
| case 's': | | case 's': | |
| return Atom(&arg->s); | | return Atom(&arg->s); | |
|
| //case 'b' | | case 'S': | |
| // FIXME: How to get a blob from a lo_arg? | | return Atom(Atom::URI, &arg->S); | |
| //return Atom(arg->b); | | case 'T': | |
| | | return Atom((bool)true); | |
| | | case 'F': | |
| | | return Atom((bool)false); | |
| default: | | default: | |
|
| | | std::cerr << "WARNING: Unable to convert OSC type '" | |
| | | << type << "' to Atom" << std::endl; | |
| return Atom(); | | return Atom(); | |
| } | | } | |
| } | | } | |
| | | | |
| } // namespace AtomLiblo | | } // namespace AtomLiblo | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_ATOM_LIBLO_HPP | | #endif // RAUL_ATOM_LIBLO_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 7 lines changed or deleted | | 25 lines changed or added | |
|
| AtomRDF.hpp | | AtomRDF.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| * with this program; if not, write to the Free Software Foundation, Inc., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_ATOM_RDF_HPP | | #ifndef RAUL_ATOM_RDF_HPP | |
| #define RAUL_ATOM_RDF_HPP | | #define RAUL_ATOM_RDF_HPP | |
| | | | |
| #include <cstring> | | #include <cstring> | |
| #include <string> | | #include <string> | |
| #include <sstream> | | #include <sstream> | |
|
| | | #include <cmath> | |
| | | | |
|
| #include CONFIG_H_PATH | | #include "raul/Atom.hpp" | |
| | | #include "redlandmm/Node.hpp" | |
| #include <redlandmm/Node.hpp> | | #include "redlandmm/World.hpp" | |
| #include <redlandmm/World.hpp> | | | |
| | | | |
| #define CUC(x) ((const unsigned char*)(x)) | | #define CUC(x) ((const unsigned char*)(x)) | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Conversion between Raul Atoms and Redlandmm RDF nodes. | | /** Conversion between Raul Atoms and Redlandmm RDF nodes. | |
| * This code (in header raul/AtomRDF.hpp) depends on redlandmm, only apps | | * This code (in header raul/AtomRDF.hpp) depends on redlandmm, only apps | |
| * which directly depend on both raul and liblo should include it. | | * which directly depend on both raul and liblo should include it. | |
| */ | | */ | |
| namespace AtomRDF { | | namespace AtomRDF { | |
| | | | |
| /** Convert a Redland::Node to a Raul::Atom */ | | /** Convert a Redland::Node to a Raul::Atom */ | |
| inline Atom | | inline Atom | |
| node_to_atom(const Redland::Node& node) | | node_to_atom(const Redland::Node& node) | |
| { | | { | |
|
| if (node.type() == Redland::Node::RESOURCE) | | if (node.is_bool()) | |
| return Atom(node.to_c_string()); | | return Atom(bool(node.to_bool())); | |
| | | else if (node.is_resource()) | |
| | | return Atom(Atom::URI, node.world()->qualify(node.to_c_strin | |
| | | g())); | |
| else if (node.is_float()) | | else if (node.is_float()) | |
| return Atom(node.to_float()); | | return Atom(node.to_float()); | |
| else if (node.is_int()) | | else if (node.is_int()) | |
| return Atom(node.to_int()); | | return Atom(node.to_int()); | |
|
| else if (node.is_bool()) | | | |
| return Atom(node.to_bool()); | | | |
| else | | else | |
| return Atom(node.to_c_string()); | | return Atom(node.to_c_string()); | |
| } | | } | |
| | | | |
|
| /** Convert a Raul::Atom to a Redland::Node */ | | /** Convert a Raul::Atom to a Redland::Node | |
| | | * Note that not all Atoms are serialisable, the returned node should | |
| | | * be checked (can be treated as a bool) before use. */ | |
| inline Redland::Node | | inline Redland::Node | |
| atom_to_node(Redland::World& world, const Atom& atom) | | atom_to_node(Redland::World& world, const Atom& atom) | |
| { | | { | |
| std::ostringstream os; | | std::ostringstream os; | |
| std::string str; | | std::string str; | |
| librdf_uri* type = NULL; | | librdf_uri* type = NULL; | |
| librdf_node* node = NULL; | | librdf_node* node = NULL; | |
| | | | |
| switch (atom.type()) { | | switch (atom.type()) { | |
| case Atom::INT: | | case Atom::INT: | |
| os << atom.get_int32(); | | os << atom.get_int32(); | |
| str = os.str(); | | str = os.str(); | |
| // xsd:integer -> pretty integer literals in Turtle | | // xsd:integer -> pretty integer literals in Turtle | |
| type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#integer")); | | type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#integer")); | |
| break; | | break; | |
| case Atom::FLOAT: | | case Atom::FLOAT: | |
|
| os.precision(20); | | if (std::isnan(atom.get_float()) || std::isinf(atom.get_floa | |
| | | t())) | |
| | | break; | |
| | | os.precision(8); | |
| os << atom.get_float(); | | os << atom.get_float(); | |
| str = os.str(); | | str = os.str(); | |
|
| | | if (str.find(".") == std::string::npos) | |
| | | str += ".0"; | |
| // xsd:decimal -> pretty decimal (float) literals in Turtle | | // xsd:decimal -> pretty decimal (float) literals in Turtle | |
| type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#decimal")); | | type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#decimal")); | |
| break; | | break; | |
| case Atom::BOOL: | | case Atom::BOOL: | |
| // xsd:boolean -> pretty boolean literals in Turtle | | // xsd:boolean -> pretty boolean literals in Turtle | |
| if (atom.get_bool()) | | if (atom.get_bool()) | |
| str = "true"; | | str = "true"; | |
| else | | else | |
| str = "false"; | | str = "false"; | |
| type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#boolean")); | | type = librdf_new_uri(world.world(), CUC("http://www.w3.org/
2001/XMLSchema#boolean")); | |
| break; | | break; | |
|
| | | case Atom::URI: | |
| | | str = atom.get_uri(); | |
| | | node = librdf_new_node_from_uri_string(world.world(), CUC(wo | |
| | | rld.expand_uri(str).c_str())); | |
| | | break; | |
| case Atom::STRING: | | case Atom::STRING: | |
| str = atom.get_string(); | | str = atom.get_string(); | |
| break; | | break; | |
| case Atom::BLOB: | | case Atom::BLOB: | |
| case Atom::NIL: | | case Atom::NIL: | |
| default: | | default: | |
|
| std::cerr << "WARNING: Unserializable Atom!" << std::endl; | | //std::cerr << "WARNING: Unserializable Atom!" << std::endl; | |
| | | break; | |
| } | | } | |
| | | | |
|
| if (str != "") | | if (!node && str != "") | |
| node = librdf_new_node_from_typed_literal(world.world(), CUC
(str.c_str()), NULL, type); | | node = librdf_new_node_from_typed_literal(world.world(), CUC
(str.c_str()), NULL, type); | |
| | | | |
| return Redland::Node(world, node); | | return Redland::Node(world, node); | |
| } | | } | |
| | | | |
| } // namespace AtomRDF | | } // namespace AtomRDF | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_ATOM_RDF_HPP | | #endif // RAUL_ATOM_RDF_HPP | |
| | | | |
End of changes. 11 change blocks. |
| 13 lines changed or deleted | | 27 lines changed or added | |
|
| AtomicInt.hpp | | AtomicInt.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 29 | | skipping to change at line 29 | |
| #define RAUL_ATOMIC_INT_HPP | | #define RAUL_ATOMIC_INT_HPP | |
| | | | |
| #include <glib.h> | | #include <glib.h> | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| class AtomicInt { | | class AtomicInt { | |
| public: | | public: | |
| | | | |
| inline AtomicInt(int val) | | inline AtomicInt(int val) | |
|
| { g_atomic_int_set(&_val, val); } | | { g_atomic_int_set(static_cast<volatile gint*>(&_val), (gint
)val); } | |
| | | | |
| inline AtomicInt(const AtomicInt& copy) | | inline AtomicInt(const AtomicInt& copy) | |
|
| { g_atomic_int_set(&_val, copy.get()); } | | { g_atomic_int_set(static_cast<volatile gint*>(&_val), (gint
)copy.get()); } | |
| | | | |
| inline int get() const | | inline int get() const | |
|
| { return g_atomic_int_get(&_val); } | | { return g_atomic_int_get(static_cast<volatile gint*>(&_val)
); } | |
| | | | |
| inline void operator=(int val) | | inline void operator=(int val) | |
|
| { g_atomic_int_set(&_val, val); } | | { g_atomic_int_set(static_cast<volatile gint*>(&_val), (gint
)val); } | |
| | | | |
| inline void operator+=(int val) | | inline void operator+=(int val) | |
|
| { g_atomic_int_add(&_val, val); } | | { g_atomic_int_add(static_cast<volatile gint*>(&_val), (gint
)val); } | |
| | | | |
| inline void operator-=(int val) | | inline void operator-=(int val) | |
|
| { g_atomic_int_add(&_val, -val); } | | { g_atomic_int_add(static_cast<volatile gint*>(&_val), (gint
)-val); } | |
| | | | |
| inline bool operator==(int val) const | | inline bool operator==(int val) const | |
| { return get() == val; } | | { return get() == val; } | |
| | | | |
| inline int operator+(int val) const | | inline int operator+(int val) const | |
| { return get() + val; } | | { return get() + val; } | |
| | | | |
| inline AtomicInt& operator++() // prefix | | inline AtomicInt& operator++() // prefix | |
|
| { g_atomic_int_inc(&_val); return *this; } | | { g_atomic_int_inc(static_cast<volatile gint*>(&_val)); retu
rn *this; } | |
| | | | |
| inline AtomicInt& operator--() // prefix | | inline AtomicInt& operator--() // prefix | |
|
| { g_atomic_int_add(&_val, -1); return *this; } | | { g_atomic_int_add(static_cast<volatile gint*>(&_val), -1);
return *this; } | |
| | | | |
|
| /** Set value to newval iff current value is oldval. | | /** Set value to @a val iff current value is @a old. | |
| * @return whether set succeeded. | | * @return true iff set succeeded. | |
| */ | | */ | |
|
| inline bool compare_and_exchange(int oldval, int newval) | | inline bool compare_and_exchange(int old, int val) | |
| { return g_atomic_int_compare_and_exchange(&_val, oldval, ne | | { return g_atomic_int_compare_and_exchange(static_cast<volat | |
| wval); } | | ile gint*>(&_val), old, val); } | |
| | | | |
| /** Add val to value. | | /** Add val to value. | |
| * @return value immediately before addition took place. | | * @return value immediately before addition took place. | |
| */ | | */ | |
| inline int exchange_and_add(int val) | | inline int exchange_and_add(int val) | |
|
| { return g_atomic_int_exchange_and_add(&_val, val); } | | { return g_atomic_int_exchange_and_add(static_cast<volatile
gint*>(&_val), val); } | |
| | | | |
| /** Decrement value. | | /** Decrement value. | |
| * @return true if value is now 0, otherwise false. | | * @return true if value is now 0, otherwise false. | |
| */ | | */ | |
| inline bool decrement_and_test() | | inline bool decrement_and_test() | |
|
| { return g_atomic_int_dec_and_test(&_val); } | | { return g_atomic_int_dec_and_test(static_cast<volatile gint
*>(&_val)); } | |
| | | | |
| private: | | private: | |
|
| volatile int _val; | | volatile mutable int _val; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_ATOMIC_INT_HPP | | #endif // RAUL_ATOMIC_INT_HPP | |
| | | | |
End of changes. 14 change blocks. |
| 17 lines changed or deleted | | 17 lines changed or added | |
|
| AtomicPtr.hpp | | AtomicPtr.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 30 | | skipping to change at line 30 | |
| | | | |
| #include <glib.h> | | #include <glib.h> | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| template<typename T> | | template<typename T> | |
| class AtomicPtr { | | class AtomicPtr { | |
| public: | | public: | |
| | | | |
| inline AtomicPtr() | | inline AtomicPtr() | |
|
| { g_atomic_pointer_set(&_val, NULL); } | | { g_atomic_pointer_set((volatile gpointer*)&_val, NULL); } | |
| | | | |
| inline AtomicPtr(const AtomicPtr& copy) | | inline AtomicPtr(const AtomicPtr& copy) | |
|
| { g_atomic_pointer_set(&_val, copy.get()); } | | { g_atomic_pointer_set((volatile gpointer*)(&_val), (gpointe
r)copy.get()); } | |
| | | | |
| inline T* get() const | | inline T* get() const | |
|
| { return (T*)g_atomic_pointer_get(&_val); } | | { return (T*)g_atomic_pointer_get((volatile gpointer*)(&_val
)); } | |
| | | | |
| inline void operator=(T* val) | | inline void operator=(T* val) | |
|
| { g_atomic_pointer_set(&_val, val); } | | { g_atomic_pointer_set(&_val, static_cast<gpointer>(val)); } | |
| | | | |
| /** Set value to newval iff current value is oldval */ | | /** Set value to newval iff current value is oldval */ | |
|
| inline bool compare_and_exchange(int oldval, int newval) | | inline bool compare_and_exchange(gpointer oldval, gpointer newval) | |
| { return g_atomic_pointer_compare_and_exchange(&_val, oldval
, newval); } | | { return g_atomic_pointer_compare_and_exchange(&_val, oldval
, newval); } | |
| | | | |
| private: | | private: | |
|
| volatile T* _val; | | mutable volatile gpointer _val; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_ATOMIC_PTR_HPP | | #endif // RAUL_ATOMIC_PTR_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 7 lines changed or deleted | | 7 lines changed or added | |
|
| Command.hpp | | Command.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_COMMAND_HPP | | #ifndef RAUL_COMMAND_HPP | |
| #define RAUL_COMMAND_HPP | | #define RAUL_COMMAND_HPP | |
| | | | |
|
| #include <raul/Semaphore.hpp> | | | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
|
| | | #include "raul/Semaphore.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** A blocking command to be executed in the audio thread. | | /** A blocking command to be executed in the audio thread. | |
| * | | * | |
| * This is useful for calling simple parameterless commands from another th
read | | * This is useful for calling simple parameterless commands from another th
read | |
| * (OSC, GUI, etc) and waiting on the result. Works well for coarsely time
d | | * (OSC, GUI, etc) and waiting on the result. Works well for coarsely time
d | |
| * events (e.g. 'play' clicked in a GUI). | | * events (e.g. 'play' clicked in a GUI). | |
| * | | * | |
|
| * Realtime safe on the commend executing side. | | * Realtime safe on the command executing side. | |
| * | | * | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
| class Command : boost::noncopyable { | | class Command : boost::noncopyable { | |
| public: | | public: | |
| inline Command() : _sem(0) {} | | inline Command() : _sem(0) {} | |
| | | | |
| /** Caller context */ | | /** Caller context */ | |
| inline void operator()() { _sem.wait(); } | | inline void operator()() { _sem.wait(); } | |
| | | | |
| | | | |
End of changes. 4 change blocks. |
| 3 lines changed or deleted | | 3 lines changed or added | |
|
| DoubleBuffer.hpp | | DoubleBuffer.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_DOUBLE_BUFFER_HPP | | #ifndef RAUL_DOUBLE_BUFFER_HPP | |
| #define RAUL_DOUBLE_BUFFER_HPP | | #define RAUL_DOUBLE_BUFFER_HPP | |
| | | | |
|
| #include <raul/AtomicInt.hpp> | | #include "raul/AtomicInt.hpp" | |
| #include <raul/AtomicPtr.hpp> | | #include "raul/AtomicPtr.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Double buffer. | | /** Double buffer. | |
| * | | * | |
| * Can be thought of as a wrapper class to make a non-atomic type atomicall
y | | * Can be thought of as a wrapper class to make a non-atomic type atomicall
y | |
| * settable (with no locking). | | * settable (with no locking). | |
| * | | * | |
| * Read/Write realtime safe, many writers safe - but set calls may fail. | | * Read/Write realtime safe, many writers safe - but set calls may fail. | |
| * | | * | |
| | | | |
End of changes. 2 change blocks. |
| 3 lines changed or deleted | | 3 lines changed or added | |
|
| List.hpp | | List.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_LIST_HPP | | #ifndef RAUL_LIST_HPP | |
| #define RAUL_LIST_HPP | | #define RAUL_LIST_HPP | |
| | | | |
| #include <cstddef> | | #include <cstddef> | |
| #include <cassert> | | #include <cassert> | |
|
| #include <raul/Deletable.hpp> | | #include <boost/utility.hpp> | |
| #include <raul/AtomicPtr.hpp> | | #include "raul/Deletable.hpp" | |
| #include <raul/AtomicInt.hpp> | | #include "raul/AtomicPtr.hpp" | |
| | | #include "raul/AtomicInt.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** A realtime safe, (partially) thread safe doubly-linked list. | | /** A realtime safe, (partially) thread safe doubly-linked list. | |
| * | | * | |
| * Elements can be added safely while another thread is reading the list. | | * Elements can be added safely while another thread is reading the list. | |
| * Like a typical ringbuffer, this is single-reader single-writer threadsaf
e | | * Like a typical ringbuffer, this is single-reader single-writer threadsaf
e | |
| * only. See documentation for specific functions for specifics. | | * only. See documentation for specific functions for specifics. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
|
| class List : public Raul::Deletable | | class List : public Raul::Deletable, public boost::noncopyable | |
| { | | { | |
| public: | | public: | |
| | | | |
| /** A node in a List. | | /** A node in a List. | |
| * | | * | |
| * This is exposed so the user can allocate Nodes in different threa
d | | * This is exposed so the user can allocate Nodes in different threa
d | |
| * than the list reader, and insert (e.g. via an Event) it later in
the | | * than the list reader, and insert (e.g. via an Event) it later in
the | |
| * reader thread. | | * reader thread. | |
| */ | | */ | |
| class Node : public Raul::Deletable { | | class Node : public Raul::Deletable { | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 70 | |
| void next(Node* ln) { _next = ln; } | | void next(Node* ln) { _next = ln; } | |
| T& elem() { return _elem;} | | T& elem() { return _elem;} | |
| const T& elem() const { return _elem; } | | const T& elem() const { return _elem; } | |
| | | | |
| private: | | private: | |
| T _elem; | | T _elem; | |
| AtomicPtr<Node> _prev; | | AtomicPtr<Node> _prev; | |
| AtomicPtr<Node> _next; | | AtomicPtr<Node> _next; | |
| }; | | }; | |
| | | | |
|
| List() : _size(0), _end_iter(this), _const_end_iter(this) { | | List(size_t size=0, Node* head=NULL, Node* tail=NULL) | |
| | | : _size(size) | |
| | | , _end_iter(this) | |
| | | , _const_end_iter(this) | |
| | | { | |
| | | _head = head; | |
| | | _tail = tail; | |
| _end_iter._listnode = NULL; | | _end_iter._listnode = NULL; | |
| _const_end_iter._listnode = NULL; | | _const_end_iter._listnode = NULL; | |
| } | | } | |
| | | | |
| ~List(); | | ~List(); | |
| | | | |
| void push_back(Node* elem); ///< Realtime Safe | | void push_back(Node* elem); ///< Realtime Safe | |
| void push_back(T& elem); ///< NOT Realtime Safe | | void push_back(T& elem); ///< NOT Realtime Safe | |
| | | | |
| void append(List<T>& list); | | void append(List<T>& list); | |
| | | | |
| skipping to change at line 106 | | skipping to change at line 113 | |
| : _list(i._list), _listnode(i._listnode) {} | | : _list(i._list), _listnode(i._listnode) {} | |
| | | | |
| inline const T& operator*(); | | inline const T& operator*(); | |
| inline const T* operator->(); | | inline const T* operator->(); | |
| inline const_iterator& operator++(); | | inline const_iterator& operator++(); | |
| inline bool operator!=(const const_iterator& iter
) const; | | inline bool operator!=(const const_iterator& iter
) const; | |
| inline bool operator!=(const iterator& iter) cons
t; | | inline bool operator!=(const iterator& iter) cons
t; | |
| inline bool operator==(const const_iterator& iter
) const; | | inline bool operator==(const const_iterator& iter
) const; | |
| inline bool operator==(const iterator& iter) cons
t; | | inline bool operator==(const iterator& iter) cons
t; | |
| | | | |
|
| | | inline typename List<T>::Node* node() { return _ | |
| | | listnode; } | |
| | | inline const typename List<T>::Node* node() const { return _ | |
| | | listnode; } | |
| | | | |
| friend class List<T>; | | friend class List<T>; | |
| | | | |
| private: | | private: | |
| const List<T>* _list; | | const List<T>* _list; | |
| const typename List<T>::Node* _listnode; | | const typename List<T>::Node* _listnode; | |
| }; | | }; | |
| | | | |
| /** Realtime safe iterator for a List. */ | | /** Realtime safe iterator for a List. */ | |
| class iterator { | | class iterator { | |
| public: | | public: | |
| | | | |
| skipping to change at line 134 | | skipping to change at line 144 | |
| inline bool operator==(const const_iterator& iter) cons
t; | | inline bool operator==(const const_iterator& iter) cons
t; | |
| | | | |
| friend class List<T>; | | friend class List<T>; | |
| friend class List<T>::const_iterator; | | friend class List<T>::const_iterator; | |
| | | | |
| private: | | private: | |
| const List<T>* _list; | | const List<T>* _list; | |
| typename List<T>::Node* _listnode; | | typename List<T>::Node* _listnode; | |
| }; | | }; | |
| | | | |
|
| | | void chop_front(List<T>& front, size_t front_size, Node* new_head); | |
| | | | |
| Node* erase(const iterator iter); | | Node* erase(const iterator iter); | |
| | | | |
| iterator find(const T& val); | | iterator find(const T& val); | |
| | | | |
| iterator begin(); | | iterator begin(); | |
| const_iterator begin() const; | | const_iterator begin() const; | |
| const iterator end() const; | | const iterator end() const; | |
| | | | |
|
| | | T& front() { return *begin(); } | |
| | | const T& front() const { return *begin(); } | |
| | | | |
| | | Node* head() { return _head.get(); } | |
| | | const Node* head() const { return _head.get(); } | |
| | | | |
| private: | | private: | |
| AtomicPtr<Node> _head; | | AtomicPtr<Node> _head; | |
| AtomicPtr<Node> _tail; ///< writer only | | AtomicPtr<Node> _tail; ///< writer only | |
| AtomicInt _size; | | AtomicInt _size; | |
| iterator _end_iter; | | iterator _end_iter; | |
| const_iterator _const_end_iter; | | const_iterator _const_end_iter; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
|
| #include "ListImpl.hpp" | | | |
| | | | |
| #endif // RAUL_LIST_HPP | | #endif // RAUL_LIST_HPP | |
|
| | | | |
| | | #include "ListImpl.hpp" | |
| | | | |
End of changes. 9 change blocks. |
| 8 lines changed or deleted | | 26 lines changed or added | |
|
| ListImpl.hpp | | ListImpl.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 107 | | skipping to change at line 107 | |
| _tail.get()->next(ln); | | _tail.get()->next(ln); | |
| _tail = ln; | | _tail = ln; | |
| } | | } | |
| ++_size; | | ++_size; | |
| } | | } | |
| | | | |
| /** Append a list to this list. | | /** Append a list to this list. | |
| * | | * | |
| * This operation is fast ( O(1) ). | | * This operation is fast ( O(1) ). | |
| * The appended list is not safe to use concurrently with this call. | | * The appended list is not safe to use concurrently with this call. | |
|
| * | | | |
| * The appended list will be empty after this call. | | * The appended list will be empty after this call. | |
| * | | * | |
| * Thread safe (may be called while another thread is reading the list). | | * Thread safe (may be called while another thread is reading the list). | |
| * Realtime safe. | | * Realtime safe. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| void | | void | |
| List<T>::append(List<T>& list) | | List<T>::append(List<T>& list) | |
| { | | { | |
| Node* const my_head = _head.get(); | | Node* const my_head = _head.get(); | |
| Node* const my_tail = _tail.get(); | | Node* const my_tail = _tail.get(); | |
| Node* const other_head = list._head.get(); | | Node* const other_head = list._head.get(); | |
| Node* const other_tail = list._tail.get(); | | Node* const other_tail = list._tail.get(); | |
| | | | |
|
| | | assert((my_head && my_tail) || (!my_head && !my_tail)); | |
| | | assert((other_head && other_tail) || (!other_head && !other_tail)); | |
| | | | |
| // Appending to an empty list | | // Appending to an empty list | |
| if (my_head == NULL && my_tail == NULL) { | | if (my_head == NULL && my_tail == NULL) { | |
| _head = other_head; | | _head = other_head; | |
| _tail = other_tail; | | _tail = other_tail; | |
| _size = list._size; | | _size = list._size; | |
| } else if (other_head != NULL && other_tail != NULL) { | | } else if (other_head != NULL && other_tail != NULL) { | |
| | | | |
| other_head->prev(my_tail); | | other_head->prev(my_tail); | |
| | | | |
| // FIXME: atomicity an issue? _size < true size is probably
fine... | | // FIXME: atomicity an issue? _size < true size is probably
fine... | |
| | | | |
| skipping to change at line 195 | | skipping to change at line 196 | |
| | | | |
| if (prev) | | if (prev) | |
| n->prev()->next(next); | | n->prev()->next(next); | |
| | | | |
| if (next) | | if (next) | |
| n->next()->prev(prev); | | n->next()->prev(prev); | |
| | | | |
| --_size; | | --_size; | |
| } | | } | |
| | | | |
|
| | | assert((_head.get() && _tail.get()) || (!_head.get() && !_tail.get()
)); | |
| return n; | | return n; | |
| } | | } | |
| | | | |
|
| | | template <typename T> | |
| | | void | |
| | | List<T>::chop_front(List<T>& front, size_t front_size, Node* new_head) | |
| | | { | |
| | | assert(new_head != _head.get()); | |
| | | assert((front._head.get() && front._tail.get()) || (!front._head.get | |
| | | () && !front._tail.get())); | |
| | | assert((_head.get() && _tail.get()) || (!_head.get() && !_tail.get() | |
| | | )); | |
| | | if (!new_head) { | |
| | | assert(front_size == static_cast<size_t>(_size.get())); | |
| | | front._size = _size; | |
| | | front._head = _head; | |
| | | front._tail = _tail; | |
| | | _size = 0; | |
| | | _head = NULL; | |
| | | _tail = NULL; | |
| | | } else { | |
| | | front._size = front_size; | |
| | | front._head = _head; | |
| | | front._tail = new_head->prev(); | |
| | | if (new_head->prev()) | |
| | | new_head->prev()->next(NULL); | |
| | | _head = new_head; | |
| | | new_head->prev(NULL); | |
| | | _size -= front_size; | |
| | | } | |
| | | assert((front._head.get() && front._tail.get()) || (!front._head.get | |
| | | () && !front._tail.get())); | |
| | | assert((_head.get() && _tail.get()) || (!_head.get() && !_tail.get() | |
| | | )); | |
| | | } | |
| | | | |
| //// Iterator stuff //// | | //// Iterator stuff //// | |
| | | | |
| template <typename T> | | template <typename T> | |
| List<T>::iterator::iterator(List<T>* list) | | List<T>::iterator::iterator(List<T>* list) | |
| : _list(list), | | : _list(list), | |
| _listnode(NULL) | | _listnode(NULL) | |
| { | | { | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| | | | |
End of changes. 5 change blocks. |
| 2 lines changed or deleted | | 38 lines changed or added | |
|
| MIDISink.hpp | | MIDISink.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_MIDI_SINK_HPP | | #ifndef RAUL_MIDI_SINK_HPP | |
| #define RAUL_MIDI_SINK_HPP | | #define RAUL_MIDI_SINK_HPP | |
| | | | |
| #include <stdexcept> | | #include <stdexcept> | |
|
| #include <raul/TimeSlice.hpp> | | #include "raul/TimeStamp.hpp" | |
| #include <raul/Deletable.hpp> | | #include "raul/Deletable.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Pure virtual base for anything you can write MIDI to. | | /** Pure virtual base for anything you can write MIDI to. | |
| */ | | */ | |
| class MIDISink : public Deletable { | | class MIDISink : public Deletable { | |
| public: | | public: | |
|
| virtual void write_event(BeatTime time, | | virtual void write_event(TimeStamp time, | |
| size_t ev_size, | | size_t ev_size, | |
| const uint8_t* ev) throw (std::logic_error)
= 0; | | const uint8_t* ev) throw (std::logic_error)
= 0; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_MIDI_SINK_HPP | | #endif // RAUL_MIDI_SINK_HPP | |
| | | | |
End of changes. 3 change blocks. |
| 4 lines changed or deleted | | 4 lines changed or added | |
|
| Maid.hpp | | Maid.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_MAID_HPP | | #ifndef RAUL_MAID_HPP | |
| #define RAUL_MAID_HPP | | #define RAUL_MAID_HPP | |
| | | | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
|
| #include <raul/SharedPtr.hpp> | | #include "raul/SharedPtr.hpp" | |
| #include <raul/SRSWQueue.hpp> | | #include "raul/SRSWQueue.hpp" | |
| #include <raul/Deletable.hpp> | | #include "raul/Deletable.hpp" | |
| #include <raul/List.hpp> | | #include "raul/List.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Explicitly driven garbage collector. | | /** Explicitly driven garbage collector. | |
| * | | * | |
| * This is used by realtime threads to allow hard realtime deletion of obje
cts | | * This is used by realtime threads to allow hard realtime deletion of obje
cts | |
| * (push() is realtime safe). | | * (push() is realtime safe). | |
| * | | * | |
| * You can also manage a SharedPtr, so cleanup() will delete it when all | | * You can also manage a SharedPtr, so cleanup() will delete it when all | |
| * references are dropped (except the one held by the Maid itself). | | * references are dropped (except the one held by the Maid itself). | |
| | | | |
End of changes. 2 change blocks. |
| 5 lines changed or deleted | | 5 lines changed or added | |
|
| Path.hpp | | Path.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| * with this program; if not, write to the Free Software Foundation, Inc., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_PATH_HPP | | #ifndef RAUL_PATH_HPP | |
| #define RAUL_PATH_HPP | | #define RAUL_PATH_HPP | |
| | | | |
| #include <iostream> | | #include <iostream> | |
| #include <cctype> | | #include <cctype> | |
| #include <string> | | #include <string> | |
|
| | | #include <cstring> | |
| #include <cassert> | | #include <cassert> | |
| | | | |
|
| | | #include "raul/Symbol.hpp" | |
| | | #include "raul/URI.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
|
| /** Simple wrapper around standard string with useful path-specific methods
. | | /** A URI which is a path (for example a filesystem or OSC path). | |
| * | | * | |
|
| * This enforces that a Path is a valid OSC path (though it is used for | | * A Path always has the special URI scheme "path:". | |
| * GraphObject paths, which aren't directly OSC paths but a portion of one) | | * | |
| . | | * This enforces that a Path is a valid path, where each fragment is a vali | |
| | | d | |
| | | * Symbol, separated by exactly one slash (/). | |
| * | | * | |
| * A path is divided by slashes (/). The first character MUST be a slash,
and | | * A path is divided by slashes (/). The first character MUST be a slash,
and | |
| * the last character MUST NOT be a slash (except in the special case of th
e | | * the last character MUST NOT be a slash (except in the special case of th
e | |
|
| * root path "/", which is the only valid single-character path). | | * root path "/", which is the only valid single-character path). The path | |
| * | | : | |
| * Valid characters are the 95 printable ASCII characters (32-126), excludi | | * scheme is added automatically (since a Patch is actually a URI). | |
| ng: | | | |
| * space # * , ? [ ] { } | | | |
| * | | * | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
|
| class Path : public std::basic_string<char> { | | class Path : public URI { | |
| public: | | public: | |
|
| | | class BadPath : public std::exception { | |
| | | public: | |
| | | BadPath(const std::string& path) : _path(path) {} | |
| | | ~BadPath() throw() {} | |
| | | const char* what() const throw() { return _path.c_str(); } | |
| | | private: | |
| | | std::string _path; | |
| | | }; | |
| | | | |
|
| /** Contrust an uninitialzed path, because the STL is annoying. */ | | static const std::string scheme; | |
| Path() : std::basic_string<char>("/") {} | | static const std::string prefix; | |
| | | static const size_t prefix_len; | |
| | | static const std::string root_uri; | |
| | | | |
| | | /** Construct an uninitialzed path, because the STL is annoying. */ | |
| | | Path() : URI(root_uri) {} | |
| | | | |
| /** Construct a Path from an std::string. | | /** Construct a Path from an std::string. | |
| * | | * | |
| * It is a fatal error to construct a Path from an invalid string, | | * It is a fatal error to construct a Path from an invalid string, | |
| * use is_valid first to check. | | * use is_valid first to check. | |
| */ | | */ | |
| Path(const std::basic_string<char>& path) | | Path(const std::basic_string<char>& path) | |
|
| : std::basic_string<char>(path) | | : URI((path.find(":") == std::string::npos) ? prefix + path
: path) | |
| { | | { | |
|
| assert(is_valid(path)); | | if (!is_valid(str())) | |
| | | throw BadPath(str()); | |
| } | | } | |
| | | | |
| /** Construct a Path from a C string. | | /** Construct a Path from a C string. | |
| * | | * | |
| * It is a fatal error to construct a Path from an invalid string, | | * It is a fatal error to construct a Path from an invalid string, | |
| * use is_valid first to check. | | * use is_valid first to check. | |
| */ | | */ | |
| Path(const char* cpath) | | Path(const char* cpath) | |
|
| : std::basic_string<char>(cpath) | | : URI((std::string(cpath).find(":") == std::string::npos) ?
prefix + cpath : cpath) | |
| { | | { | |
|
| assert(is_valid(cpath)); | | if (!is_valid(str())) | |
| | | throw BadPath(str()); | |
| } | | } | |
| | | | |
| static bool is_valid(const std::basic_string<char>& path); | | static bool is_valid(const std::basic_string<char>& path); | |
| | | | |
| static bool is_valid_name(const std::basic_string<char>& name) { | | static bool is_valid_name(const std::basic_string<char>& name) { | |
|
| return name.length() > 0 && is_valid(std::string("/").append | | return name.length() > 0 && name.find("/") == std::string::n | |
| (name)); | | pos | |
| | | && is_valid(std::string("/").append(name)); | |
| } | | } | |
| | | | |
| static std::string pathify(const std::basic_string<char>& str); | | static std::string pathify(const std::basic_string<char>& str); | |
| static std::string nameify(const std::basic_string<char>& str); | | static std::string nameify(const std::basic_string<char>& str); | |
| | | | |
|
| static void replace_invalid_chars(std::string& str, bool replace_sla | | static void replace_invalid_chars(std::string& str, size_t start, bo | |
| sh = false); | | ol replace_slash = false); | |
| | | | |
| | | bool is_root() const { return str() == root_uri; } | |
| | | | |
| bool is_child_of(const Path& parent) const; | | bool is_child_of(const Path& parent) const; | |
| bool is_parent_of(const Path& child) const; | | bool is_parent_of(const Path& child) const; | |
| | | | |
|
| | | Path child(const std::string& s) const { | |
| | | if (is_valid(s)) | |
| | | return std::string(base()) + Path(s).chop_scheme().s | |
| | | ubstr(1); | |
| | | else | |
| | | return std::string(base()) + s; | |
| | | } | |
| | | | |
| | | Path operator+(const Path& p) const { return child(p); } | |
| | | | |
| /** Return the name of this object (everything after the last '/'). | | /** Return the name of this object (everything after the last '/'). | |
| * This is the "method name" for OSC paths. | | * This is the "method name" for OSC paths. | |
|
| | | * The empty string may be returned (if the path is "/"). | |
| */ | | */ | |
|
| inline std::basic_string<char> name() const { | | inline std::string name() const { | |
| if ((*this) == "/") | | if (str() == root_uri) | |
| return ""; | | return ""; | |
| else | | else | |
| return substr(find_last_of("/")+1); | | return substr(find_last_of("/")+1); | |
| } | | } | |
| | | | |
|
| | | /** Return the name of this object (everything after the last '/'). | |
| | | * This is the "method name" for OSC paths. | |
| | | * Note it is illegal to call this method on the path "/". | |
| | | */ | |
| | | inline Symbol symbol() const { | |
| | | return substr(find_last_of("/")+1); | |
| | | } | |
| | | | |
| /** Return the parent's path. | | /** Return the parent's path. | |
| * | | * | |
| * Calling this on the path "/" will return "/". | | * Calling this on the path "/" will return "/". | |
| * This is the (deepest) "container path" for OSC paths. | | * This is the (deepest) "container path" for OSC paths. | |
| */ | | */ | |
| inline Path parent() const { | | inline Path parent() const { | |
|
| std::basic_string<char> parent = substr(0, find_last_of("/") | | if (str() == root_uri) { | |
| ); | | return str(); | |
| return (parent == "") ? "/" : parent; | | } else { | |
| | | size_t last_slash = find_last_of("/"); | |
| | | return (last_slash == prefix_len) ? root_uri : subst | |
| | | r(0, last_slash); | |
| | | } | |
| | | } | |
| | | | |
| | | /** Return path relative to some base path (chop prefix) | |
| | | */ | |
| | | inline Path relative_to_base(const Path& base) const { | |
| | | if (str() == base) { | |
| | | return "/"; | |
| | | } else { | |
| | | assert(length() > base.length()); | |
| | | return substr(base.length() - 1); | |
| | | } | |
| } | | } | |
| | | | |
| /** Return path with a trailing "/". | | /** Return path with a trailing "/". | |
| * | | * | |
| * Returned value is guaranteed to be a valid parent path, i.e. a va
lid | | * Returned value is guaranteed to be a valid parent path, i.e. a va
lid | |
| * child path can be made using parent.base() + child_name. | | * child path can be made using parent.base() + child_name. | |
| */ | | */ | |
| inline const std::string base() const { | | inline const std::string base() const { | |
|
| if ((*this) == "/") | | if (str() == root_uri) | |
| return *this; | | return str(); | |
| else | | else | |
|
| return (*this) + "/"; | | return str() + "/"; | |
| } | | } | |
| | | | |
| /** Return true if \a child is equal to, or a descendant of \a paren
t */ | | /** Return true if \a child is equal to, or a descendant of \a paren
t */ | |
| static bool descendant_comparator(const Path& parent, const Path& ch
ild) { | | static bool descendant_comparator(const Path& parent, const Path& ch
ild) { | |
| return ( child == parent || (child.length() > parent.length(
) && | | return ( child == parent || (child.length() > parent.length(
) && | |
|
| (!strncmp(parent.c_str(), child.c_str(), par | | (!std::strncmp(parent.c_str(), child.c_str() | |
| ent.length()) | | , parent.length()) | |
| && (parent == "/" || child[p | | && (parent.str() == root_uri | |
| arent.length()] == '/'))) ); | | || child[parent.length()] == '/'))) ); | |
| } | | } | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_PATH_HPP | | #endif // RAUL_PATH_HPP | |
| | | | |
End of changes. 23 change blocks. |
| 33 lines changed or deleted | | 89 lines changed or added | |
|
| PathTable.hpp | | PathTable.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_PATH_TABLE_HPP | | #ifndef RAUL_PATH_TABLE_HPP | |
| #define RAUL_PATH_TABLE_HPP | | #define RAUL_PATH_TABLE_HPP | |
| | | | |
|
| #include <raul/Path.hpp> | | #include "raul/Path.hpp" | |
| #include <raul/Table.hpp> | | #include "raul/Table.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| template <typename T> | | template <typename T> | |
| class PathTable : public Table<Path, T> { | | class PathTable : public Table<Path, T> { | |
| public: | | public: | |
| /** Find all descendants of a Path key in the Table. | | /** Find all descendants of a Path key in the Table. | |
| * It is guaranteed that (parent, parent+1, parent+2, ..., ret-1) ar
e all | | * It is guaranteed that (parent, parent+1, parent+2, ..., ret-1) ar
e all | |
| * descendants of parent. The return value is never a descendent of | | * descendants of parent. The return value is never a descendent of | |
| * parent, and may be end(). | | * parent, and may be end(). | |
| | | | |
End of changes. 2 change blocks. |
| 3 lines changed or deleted | | 3 lines changed or added | |
|
| Quantizer.hpp | | Quantizer.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_QUANTIZER_HPP | | #ifndef RAUL_QUANTIZER_HPP | |
| #define RAUL_QUANTIZER_HPP | | #define RAUL_QUANTIZER_HPP | |
| | | | |
| #include <cmath> | | #include <cmath> | |
|
| | | #include "raul/TimeStamp.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| class Quantizer { | | class Quantizer { | |
| public: | | public: | |
|
| inline static double quantize(double q, double value) { | | inline static TimeStamp quantize(TimeStamp q, TimeStamp t) { | |
| return (q > 0) ? lrint(value / q) * q : value; | | assert(q.unit() == t.unit()); | |
| | | // FIXME: Precision problem? Should probably stay in discre | |
| | | te domain | |
| | | const double qd = q.to_double(); | |
| | | const double td = t.to_double(); | |
| | | return TimeStamp(t.unit(), (qd > 0) ? lrint(td / qd) * qd : | |
| | | td); | |
| | | } | |
| | | | |
| | | inline static double quantize(double q, double t) { | |
| | | return (q > 0) | |
| | | ? lrint(t / q) * q | |
| | | : t; | |
| } | | } | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_QUANTIZER_HPP | | #endif // RAUL_QUANTIZER_HPP | |
| | | | |
End of changes. 3 change blocks. |
| 3 lines changed or deleted | | 16 lines changed or added | |
|
| RingBuffer.hpp | | RingBuffer.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_RING_BUFFER_HPP | | #ifndef RAUL_RING_BUFFER_HPP | |
| #define RAUL_RING_BUFFER_HPP | | #define RAUL_RING_BUFFER_HPP | |
| | | | |
| #include <cassert> | | #include <cassert> | |
|
| | | #include <cstring> | |
| | | #include <iostream> | |
| #include <glib.h> | | #include <glib.h> | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** A lock-free RingBuffer. | | /** A lock-free RingBuffer. | |
| * Read/Write realtime safe. | | * Read/Write realtime safe. | |
| * Single-reader Single-writer thread safe. | | * Single-reader Single-writer thread safe. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| class RingBuffer { | | class RingBuffer { | |
| | | | |
| skipping to change at line 58 | | skipping to change at line 60 | |
| | | | |
| /** Reset(empty) the ringbuffer. | | /** Reset(empty) the ringbuffer. | |
| * NOT thread safe. | | * NOT thread safe. | |
| */ | | */ | |
| void reset() { | | void reset() { | |
| g_atomic_int_set(&_write_ptr, 0); | | g_atomic_int_set(&_write_ptr, 0); | |
| g_atomic_int_set(&_read_ptr, 0); | | g_atomic_int_set(&_read_ptr, 0); | |
| } | | } | |
| | | | |
| size_t write_space() const { | | size_t write_space() const { | |
|
| | | | |
| const size_t w = g_atomic_int_get(&_write_ptr); | | const size_t w = g_atomic_int_get(&_write_ptr); | |
| const size_t r = g_atomic_int_get(&_read_ptr); | | const size_t r = g_atomic_int_get(&_read_ptr); | |
| | | | |
| if (w > r) { | | if (w > r) { | |
| return ((r - w + _size) % _size) - 1; | | return ((r - w + _size) % _size) - 1; | |
|
| } else if(w < r) { | | } else if (w < r) { | |
| return (r - w) - 1; | | return (r - w) - 1; | |
| } else { | | } else { | |
| return _size - 1; | | return _size - 1; | |
| } | | } | |
| } | | } | |
| | | | |
| size_t read_space() const { | | size_t read_space() const { | |
|
| | | | |
| const size_t w = g_atomic_int_get(&_write_ptr); | | const size_t w = g_atomic_int_get(&_write_ptr); | |
| const size_t r = g_atomic_int_get(&_read_ptr); | | const size_t r = g_atomic_int_get(&_read_ptr); | |
| | | | |
| if (w > r) { | | if (w > r) { | |
| return w - r; | | return w - r; | |
| } else { | | } else { | |
| return (w - r + _size) % _size; | | return (w - r + _size) % _size; | |
| } | | } | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 85 | | skipping to change at line 85 | |
| | | | |
| if (w > r) { | | if (w > r) { | |
| return w - r; | | return w - r; | |
| } else { | | } else { | |
| return (w - r + _size) % _size; | | return (w - r + _size) % _size; | |
| } | | } | |
| } | | } | |
| | | | |
| size_t capacity() const { return _size; } | | size_t capacity() const { return _size; } | |
| | | | |
|
| size_t read(size_t size, T* dst); | | size_t peek(size_t size, T* dst); | |
| void write(size_t size, const T* src); | | bool full_peek(size_t size, T* dst); | |
| | | | |
|
| | | size_t read(size_t size, T* dst); | |
| bool full_read(size_t size, T* dst); | | bool full_read(size_t size, T* dst); | |
| | | | |
|
| | | bool skip(size_t size); | |
| | | | |
| | | void write(size_t size, const T* src); | |
| | | | |
| protected: | | protected: | |
|
| mutable gint _write_ptr; | | mutable int _write_ptr; | |
| mutable gint _read_ptr; | | mutable int _read_ptr; | |
| | | | |
| size_t _size; ///< Size (capacity) in bytes | | size_t _size; ///< Size (capacity) in bytes | |
|
| T* _buf; ///< size, event, size, event... | | T* _buf; ///< size, event, size, event... | |
| }; | | }; | |
| | | | |
|
| | | /** Peek at the ringbuffer (read w/o advancing read pointer). | |
| | | * | |
| | | * Note that a full read may not be done if the data wraps around. | |
| | | * Caller must check return value and call again if necessary, or use the | |
| | | * full_peek method which does this automatically. | |
| | | */ | |
| | | template<typename T> | |
| | | size_t | |
| | | RingBuffer<T>::peek(size_t size, T* dst) | |
| | | { | |
| | | const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); | |
| | | | |
| | | const size_t read_size = (priv_read_ptr + size < _size) | |
| | | ? size | |
| | | : _size - priv_read_ptr; | |
| | | | |
| | | memcpy(dst, &_buf[priv_read_ptr], read_size); | |
| | | | |
| | | return read_size; | |
| | | } | |
| | | | |
| | | template<typename T> | |
| | | bool | |
| | | RingBuffer<T>::full_peek(size_t size, T* dst) | |
| | | { | |
| | | if (read_space() < size) { | |
| | | return false; | |
| | | } | |
| | | | |
| | | const size_t read_size = peek(size, dst); | |
| | | | |
| | | if (read_size < size) { | |
| | | peek(size - read_size, dst + read_size); | |
| | | } | |
| | | | |
| | | return true; | |
| | | } | |
| | | | |
| /** Read from the ringbuffer. | | /** Read from the ringbuffer. | |
| * | | * | |
| * Note that a full read may not be done if the data wraps around. | | * Note that a full read may not be done if the data wraps around. | |
| * Caller must check return value and call again if necessary, or use the | | * Caller must check return value and call again if necessary, or use the | |
| * full_read method which does this automatically. | | * full_read method which does this automatically. | |
| */ | | */ | |
| template<typename T> | | template<typename T> | |
| size_t | | size_t | |
| RingBuffer<T>::read(size_t size, T* dst) | | RingBuffer<T>::read(size_t size, T* dst) | |
| { | | { | |
| | | | |
| skipping to change at line 122 | | skipping to change at line 165 | |
| : _size - priv_read_ptr; | | : _size - priv_read_ptr; | |
| | | | |
| memcpy(dst, &_buf[priv_read_ptr], read_size); | | memcpy(dst, &_buf[priv_read_ptr], read_size); | |
| | | | |
| g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); | | g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); | |
| | | | |
| return read_size; | | return read_size; | |
| } | | } | |
| | | | |
| template<typename T> | | template<typename T> | |
|
| | | bool | |
| | | RingBuffer<T>::full_read(size_t size, T* dst) | |
| | | { | |
| | | if (read_space() < size) { | |
| | | return false; | |
| | | } | |
| | | | |
| | | const size_t read_size = read(size, dst); | |
| | | | |
| | | if (read_size < size) { | |
| | | read(size - read_size, dst + read_size); | |
| | | } | |
| | | | |
| | | return true; | |
| | | } | |
| | | | |
| | | template<typename T> | |
| | | bool | |
| | | RingBuffer<T>::skip(size_t size) | |
| | | { | |
| | | if (read_space() < size) { | |
| | | std::cerr << "WARNING: Attempt to skip past end of MIDI ring | |
| | | buffer" << std::endl; | |
| | | return false; | |
| | | } | |
| | | | |
| | | const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); | |
| | | g_atomic_int_set(&_read_ptr, (priv_read_ptr + size) % _size); | |
| | | | |
| | | return true; | |
| | | } | |
| | | | |
| | | template<typename T> | |
| inline void | | inline void | |
| RingBuffer<T>::write(size_t size, const T* src) | | RingBuffer<T>::write(size_t size, const T* src) | |
| { | | { | |
| const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); | | const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); | |
| | | | |
| if (priv_write_ptr + size <= _size) { | | if (priv_write_ptr + size <= _size) { | |
| memcpy(&_buf[priv_write_ptr], src, size); | | memcpy(&_buf[priv_write_ptr], src, size); | |
|
| g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size); | | g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _siz
e); | |
| } else { | | } else { | |
| const size_t this_size = _size - priv_write_ptr; | | const size_t this_size = _size - priv_write_ptr; | |
| assert(this_size < size); | | assert(this_size < size); | |
| assert(priv_write_ptr + this_size <= _size); | | assert(priv_write_ptr + this_size <= _size); | |
| memcpy(&_buf[priv_write_ptr], src, this_size); | | memcpy(&_buf[priv_write_ptr], src, this_size); | |
| memcpy(&_buf[0], src+this_size, size - this_size); | | memcpy(&_buf[0], src+this_size, size - this_size); | |
|
| g_atomic_int_set(&_write_ptr, size - this_size); | | g_atomic_int_set(&_write_ptr, size - this_size); | |
| } | | } | |
| } | | } | |
| | | | |
|
| template<typename T> | | | |
| bool | | | |
| RingBuffer<T>::full_read(size_t size, T* dst) | | | |
| { | | | |
| if (read_space() < size) | | | |
| return false; | | | |
| | | | |
| const size_t read_size = read(size, dst); | | | |
| | | | |
| if (read_size < size) | | | |
| read(size - read_size, dst + read_size); | | | |
| | | | |
| return true; | | | |
| } | | | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_RING_BUFFER_HPP | | #endif // RAUL_RING_BUFFER_HPP | |
| | | | |
End of changes. 15 change blocks. |
| 26 lines changed or deleted | | 87 lines changed or added | |
|
| SMFReader.hpp | | SMFReader.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| * with this program; if not, write to the Free Software Foundation, Inc., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_SMF_READER_HPP | | #ifndef RAUL_SMF_READER_HPP | |
| #define RAUL_SMF_READER_HPP | | #define RAUL_SMF_READER_HPP | |
| | | | |
| #include <stdexcept> | | #include <stdexcept> | |
| #include <string> | | #include <string> | |
| #include <inttypes.h> | | #include <inttypes.h> | |
|
| | | #include "raul/TimeStamp.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Standard Midi File (Type 0) Reader | | /** Standard Midi File (Type 0) Reader | |
| * | | * | |
| * Currently this only reads SMF files with tempo-based timing. | | * Currently this only reads SMF files with tempo-based timing. | |
| */ | | */ | |
| class SMFReader { | | class SMFReader { | |
| public: | | public: | |
|
| SMFReader(); | | class PrematureEOF : public std::exception { | |
| | | const char* what() const throw() { return "Unexpected end of | |
| | | file"; } | |
| | | }; | |
| | | class CorruptFile : public std::exception { | |
| | | const char* what() const throw() { return "Corrupted file"; | |
| | | } | |
| | | }; | |
| | | class UnsupportedTime : public std::exception { | |
| | | const char* what() const throw() { return "Unsupported time | |
| | | stamp type (SMPTE)"; } | |
| | | }; | |
| | | | |
| | | SMFReader(const std::string filename=""); | |
| ~SMFReader(); | | ~SMFReader(); | |
| | | | |
|
| bool open(const std::string& filename); | | bool open(const std::string& filename) throw (std::logic_error, Unsu
pportedTime); | |
| | | | |
| bool seek_to_track(unsigned track) throw (std::logic_error); | | bool seek_to_track(unsigned track) throw (std::logic_error); | |
| | | | |
| uint16_t type() const { return _type; } | | uint16_t type() const { return _type; } | |
| uint16_t ppqn() const { return _ppqn; } | | uint16_t ppqn() const { return _ppqn; } | |
| size_t num_tracks() { return _num_tracks; } | | size_t num_tracks() { return _num_tracks; } | |
| | | | |
| int read_event(size_t buf_len, | | int read_event(size_t buf_len, | |
| uint8_t* buf, | | uint8_t* buf, | |
| uint32_t* ev_size, | | uint32_t* ev_size, | |
|
| uint32_t* ev_delta_time) throw (std::logic_error); | | uint32_t* ev_delta_time) | |
| | | throw (std::logic_error, PrematureEOF, CorruptFile); | |
| | | | |
| void close(); | | void close(); | |
| | | | |
|
| | | static uint32_t read_var_len(FILE* fd) throw (PrematureEOF); | |
| | | | |
| protected: | | protected: | |
| /** size of SMF header, including MTrk chunk header */ | | /** size of SMF header, including MTrk chunk header */ | |
| static const uint32_t HEADER_SIZE = 22; | | static const uint32_t HEADER_SIZE = 22; | |
| | | | |
|
| uint32_t read_var_len() const; | | std::string _filename; | |
| | | FILE* _fd; | |
| std::string _filename; | | uint16_t _type; | |
| FILE* _fd; | | uint16_t _ppqn; | |
| uint16_t _type; | | uint16_t _num_tracks; | |
| uint16_t _ppqn; | | uint32_t _track; | |
| uint16_t _num_tracks; | | uint32_t _track_size; | |
| uint32_t _track; | | | |
| uint32_t _track_size; | | | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_SMF_READER_HPP | | #endif // RAUL_SMF_READER_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 13 lines changed or deleted | | 28 lines changed or added | |
|
| SMFWriter.hpp | | SMFWriter.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_SMF_WRITER_HPP | | #ifndef RAUL_SMF_WRITER_HPP | |
| #define RAUL_SMF_WRITER_HPP | | #define RAUL_SMF_WRITER_HPP | |
| | | | |
| #include <stdexcept> | | #include <stdexcept> | |
|
| #include <raul/MIDISink.hpp> | | #include "raul/MIDISink.hpp" | |
| | | #include "raul/TimeStamp.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Standard Midi File (Type 0) Writer | | /** Standard Midi File (Type 0) Writer | |
| */ | | */ | |
| class SMFWriter : public Raul::MIDISink { | | class SMFWriter : public Raul::MIDISink { | |
| public: | | public: | |
|
| SMFWriter(unsigned short ppqn=1920); | | SMFWriter(TimeUnit unit); | |
| ~SMFWriter(); | | ~SMFWriter(); | |
| | | | |
| bool start(const std::string& filename, | | bool start(const std::string& filename, | |
|
| BeatTime start_time=0) throw (std::logic_error)
; | | TimeStamp start_time) throw (std::logic_error); | |
| | | | |
|
| uint16_t ppqn() const { return _ppqn; } | | TimeUnit unit() const { return _unit; } | |
| | | | |
|
| void write_event(BeatTime time, | | void write_event(TimeStamp time, | |
| size_t ev_size, | | size_t ev_size, | |
| const unsigned char* ev) throw (std::logic_error); | | const unsigned char* ev) throw (std::logic_error); | |
| | | | |
| void flush(); | | void flush(); | |
| | | | |
| void finish() throw (std::logic_error); | | void finish() throw (std::logic_error); | |
| | | | |
| protected: | | protected: | |
| static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; | | static const uint32_t VAR_LEN_MAX = 0x0FFFFFFF; | |
| | | | |
| void write_header(); | | void write_header(); | |
| void write_footer(); | | void write_footer(); | |
| | | | |
| void write_chunk_header(const char id[4], uint32_t length); | | void write_chunk_header(const char id[4], uint32_t length); | |
| void write_chunk(const char id[4], uint32_t length, void* data); | | void write_chunk(const char id[4], uint32_t length, void* data); | |
| size_t write_var_len(uint32_t val); | | size_t write_var_len(uint32_t val); | |
| | | | |
|
| std::string _filename; | | std::string _filename; | |
| FILE* _fd; | | FILE* _fd; | |
| uint16_t _ppqn; | | TimeUnit _unit; | |
| Raul::BeatTime _start_time; | | Raul::TimeStamp _start_time; | |
| Raul::BeatTime _last_ev_time; ///< Time last event was written relat | | Raul::TimeStamp _last_ev_time; ///< Time last event was written rela | |
| ive to _start_time | | tive to _start_time | |
| uint32_t _track_size; | | uint32_t _track_size; | |
| uint32_t _header_size; ///< size of SMF header, including MTrk | | uint32_t _header_size; ///< size of SMF header, including MTr | |
| chunk header | | k chunk header | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_SMF_WRITER_HPP | | #endif // RAUL_SMF_WRITER_HPP | |
| | | | |
End of changes. 7 change blocks. |
| 15 lines changed or deleted | | 16 lines changed or added | |
|
| SRMWQueue.hpp | | SRMWQueue.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 25 | | skipping to change at line 25 | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_SRMW_QUEUE_HPP | | #ifndef RAUL_SRMW_QUEUE_HPP | |
| #define RAUL_SRMW_QUEUE_HPP | | #define RAUL_SRMW_QUEUE_HPP | |
| | | | |
| #include <cassert> | | #include <cassert> | |
| #include <cstdlib> | | #include <cstdlib> | |
| #include <cmath> | | #include <cmath> | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
|
| #include <raul/AtomicInt.hpp> | | #include "raul/AtomicInt.hpp" | |
| | | | |
| #include <iostream> | | | |
| using namespace std; | | | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Realtime-safe single-reader multi-writer queue (aka lock-free ringbuffe
r) | | /** Realtime-safe single-reader multi-writer queue (aka lock-free ringbuffe
r) | |
| * | | * | |
| * Implemented as a dequeue in a fixed array. Both push and pop are realti
me | | * Implemented as a dequeue in a fixed array. Both push and pop are realti
me | |
| * safe, but only push is threadsafe. In other words, multiple threads can
push | | * safe, but only push is threadsafe. In other words, multiple threads can
push | |
| * data into this queue for a single thread to consume. | | * data into this queue for a single thread to consume. | |
| * | | * | |
| * The interface is intentionally as similar to std::queue as possible, but | | * The interface is intentionally as similar to std::queue as possible, but | |
| | | | |
End of changes. 2 change blocks. |
| 5 lines changed or deleted | | 2 lines changed or added | |
|
| SRSWQueue.hpp | | SRSWQueue.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| * with this program; if not, write to the Free Software Foundation, Inc., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_SRSW_QUEUE_HPP | | #ifndef RAUL_SRSW_QUEUE_HPP | |
| #define RAUL_SRSW_QUEUE_HPP | | #define RAUL_SRSW_QUEUE_HPP | |
| | | | |
| #include <cassert> | | #include <cassert> | |
| #include <cstdlib> | | #include <cstdlib> | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
|
| #include <raul/AtomicInt.hpp> | | #include "raul/AtomicInt.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Realtime-safe single-reader single-writer queue (aka lock-free ringbuff
er) | | /** Realtime-safe single-reader single-writer queue (aka lock-free ringbuff
er) | |
| * | | * | |
| * Implemented as a dequeue in a fixed array. This is read/write thread-sa
fe, | | * Implemented as a dequeue in a fixed array. This is read/write thread-sa
fe, | |
| * pushing and popping may occur simultaneously by seperate threads, but | | * pushing and popping may occur simultaneously by seperate threads, but | |
| * the push and pop operations themselves are not thread-safe (ie. there ca
n | | * the push and pop operations themselves are not thread-safe (ie. there ca
n | |
| * be at most 1 read and at most 1 writer thread). | | * be at most 1 read and at most 1 writer thread). | |
| * | | * | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| inline bool full() const; | | inline bool full() const; | |
| inline bool push(const T& obj); | | inline bool push(const T& obj); | |
| | | | |
| // Read thread: | | // Read thread: | |
| | | | |
| inline bool empty() const; | | inline bool empty() const; | |
| inline T& front() const; | | inline T& front() const; | |
| inline void pop(); | | inline void pop(); | |
| | | | |
| private: | | private: | |
|
| volatile size_t _front; ///< Index to front of queue (circular) | | AtomicInt _front; ///< Index to front of queue (circular) | |
| volatile size_t _back; ///< Index to back of queue (one past last | | AtomicInt _back; ///< Index to back of queue (one past last el | |
| element) (circular) | | ement) (circular) | |
| const size_t _size; ///< Size of @ref _objects (you can store | | const size_t _size; ///< Size of @ref _objects (you can store _si | |
| _size-1 objects) | | ze-1 objects) | |
| T* const _objects; ///< Fixed array containing queued element | | T* const _objects; ///< Fixed array containing queued elements | |
| s | | | |
| }; | | }; | |
| | | | |
| template<typename T> | | template<typename T> | |
| SRSWQueue<T>::SRSWQueue(size_t size) | | SRSWQueue<T>::SRSWQueue(size_t size) | |
|
| : _front(0), | | : _front(0) | |
| _back(0), | | , _back(0) | |
| _size(size+1), | | , _size(size+1) | |
| _objects((T*)calloc(_size, sizeof(T))) | | , _objects((T*)calloc(_size, sizeof(T))) | |
| { | | { | |
| assert(size > 1); | | assert(size > 1); | |
| } | | } | |
| | | | |
| template <typename T> | | template <typename T> | |
| SRSWQueue<T>::~SRSWQueue() | | SRSWQueue<T>::~SRSWQueue() | |
| { | | { | |
| free(_objects); | | free(_objects); | |
| } | | } | |
| | | | |
| /** Return whether or not the queue is empty. | | /** Return whether or not the queue is empty. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| inline bool | | inline bool | |
| SRSWQueue<T>::empty() const | | SRSWQueue<T>::empty() const | |
| { | | { | |
|
| return (_back == _front); | | return (_back.get() == _front.get()); | |
| } | | } | |
| | | | |
| /** Return whether or not the queue is full. | | /** Return whether or not the queue is full. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| inline bool | | inline bool | |
| SRSWQueue<T>::full() const | | SRSWQueue<T>::full() const | |
| { | | { | |
|
| // FIXME: uses both _front and _back - thread safe? | | return (((_front.get() - _back.get() + _size) % _size) == 1); | |
| return ( ((_front - _back + _size) % _size) == 1 ); | | | |
| } | | } | |
| | | | |
| /** Return the element at the front of the queue without removing it | | /** Return the element at the front of the queue without removing it | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| inline T& | | inline T& | |
| SRSWQueue<T>::front() const | | SRSWQueue<T>::front() const | |
| { | | { | |
|
| return _objects[_front]; | | return _objects[_front.get()]; | |
| } | | } | |
| | | | |
| /** Push an item onto the back of the SRSWQueue - realtime-safe, not thread
-safe. | | /** Push an item onto the back of the SRSWQueue - realtime-safe, not thread
-safe. | |
| * | | * | |
| * @returns true if @a elem was successfully pushed onto the queue, | | * @returns true if @a elem was successfully pushed onto the queue, | |
| * false otherwise (queue is full). | | * false otherwise (queue is full). | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| inline bool | | inline bool | |
| SRSWQueue<T>::push(const T& elem) | | SRSWQueue<T>::push(const T& elem) | |
| { | | { | |
| if (full()) { | | if (full()) { | |
| return false; | | return false; | |
| } else { | | } else { | |
|
| _objects[_back] = elem; | | unsigned back = _back.get(); | |
| _back = (_back + 1) % (_size); | | _objects[back] = elem; | |
| | | _back = (back + 1) % _size; | |
| return true; | | return true; | |
| } | | } | |
| } | | } | |
| | | | |
| /** Pop an item off the front of the queue - realtime-safe, not thread-safe
. | | /** Pop an item off the front of the queue - realtime-safe, not thread-safe
. | |
| * | | * | |
| * It is a fatal error to call pop() when the queue is empty. | | * It is a fatal error to call pop() when the queue is empty. | |
| * | | * | |
| * @returns the element popped. | | * @returns the element popped. | |
| */ | | */ | |
| template <typename T> | | template <typename T> | |
| inline void | | inline void | |
| SRSWQueue<T>::pop() | | SRSWQueue<T>::pop() | |
| { | | { | |
| assert(!empty()); | | assert(!empty()); | |
| assert(_size > 0); | | assert(_size > 0); | |
| | | | |
|
| _front = (_front + 1) % (_size); | | _front = (_front.get() + 1) % (_size); | |
| } | | } | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_SRSW_QUEUE_HPP | | #endif // RAUL_SRSW_QUEUE_HPP | |
| | | | |
End of changes. 9 change blocks. |
| 20 lines changed or deleted | | 19 lines changed or added | |
|
| Semaphore.hpp | | Semaphore.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 28 | | skipping to change at line 28 | |
| #ifndef RAUL_SEMAPHORE_HPP | | #ifndef RAUL_SEMAPHORE_HPP | |
| #define RAUL_SEMAPHORE_HPP | | #define RAUL_SEMAPHORE_HPP | |
| | | | |
| #include <semaphore.h> | | #include <semaphore.h> | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Trivial wrapper around POSIX semaphores (zero memory overhead). | | /** Trivial wrapper around POSIX semaphores (zero memory overhead). | |
| * | | * | |
|
| * This was created to provide an alternative debuggable implementation of | | | |
| * semaphores based on a cond/mutex pair because semaphore's appeared not t | | | |
| o | | | |
| * work in GDB. Turns out sem_wait can fail when run in GDB, and Debian | | | |
| * really needs to update it's man pages. | | | |
| * | | | |
| * This class remains as a trivial (yet pretty) wrapper/abstraction, becaus | | | |
| e | | | |
| * Glib (idiotically) doesn't have a Semaphore class. | | | |
| * | | | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
| class Semaphore : boost::noncopyable { | | class Semaphore : boost::noncopyable { | |
| public: | | public: | |
| inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial)
; } | | inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial)
; } | |
| | | | |
| inline ~Semaphore() { sem_destroy(&_sem); } | | inline ~Semaphore() { sem_destroy(&_sem); } | |
| | | | |
| inline void reset(unsigned int initial) { | | inline void reset(unsigned int initial) { | |
| sem_destroy(&_sem); | | sem_destroy(&_sem); | |
| | | | |
| skipping to change at line 68 | | skipping to change at line 60 | |
| */ | | */ | |
| inline void post() { sem_post(&_sem); } | | inline void post() { sem_post(&_sem); } | |
| | | | |
| /** Wait until count is > 0, then decrement. | | /** Wait until count is > 0, then decrement. | |
| * | | * | |
| * Note that sem_wait always returns 0 in practise. It returns nonz
ero | | * Note that sem_wait always returns 0 in practise. It returns nonz
ero | |
| * when run in GDB, so the while is necessary to allow debugging. | | * when run in GDB, so the while is necessary to allow debugging. | |
| * | | * | |
| * Obviously not realtime safe. | | * Obviously not realtime safe. | |
| */ | | */ | |
|
| inline void wait() { while (sem_wait(&_sem) != 0) ; } | | inline void wait() { while (sem_wait(&_sem) != 0) {} } | |
| | | | |
| /** Non-blocking version of wait(). | | /** Non-blocking version of wait(). | |
| * | | * | |
| * \return true if decrement was successful (lock was acquired). | | * \return true if decrement was successful (lock was acquired). | |
| * | | * | |
| * Realtime safe? | | * Realtime safe? | |
| */ | | */ | |
| inline bool try_wait() { return (sem_trywait(&_sem) == 0); } | | inline bool try_wait() { return (sem_trywait(&_sem) == 0); } | |
| | | | |
| private: | | private: | |
| | | | |
End of changes. 3 change blocks. |
| 12 lines changed or deleted | | 2 lines changed or added | |
|
| Slave.hpp | | Slave.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| * You should have received a copy of the GNU General Public License along | | * 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., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_SLAVE_HPP | | #ifndef RAUL_SLAVE_HPP | |
| #define RAUL_SLAVE_HPP | | #define RAUL_SLAVE_HPP | |
| | | | |
| #include <pthread.h> | | #include <pthread.h> | |
|
| #include <raul/Semaphore.hpp> | | #include "raul/Semaphore.hpp" | |
| #include <raul/Thread.hpp> | | #include "raul/Thread.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /** Thread driven by (realtime safe) signals. | | /** Thread driven by (realtime safe) signals. | |
| * | | * | |
| * Use this to perform some task in a separate thread you want to 'drive' | | * Use this to perform some task in a separate thread you want to 'drive' | |
| * from a realtime (or otherwise) thread. | | * from a realtime (or otherwise) thread. | |
| * | | * | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
| | | | |
End of changes. 2 change blocks. |
| 3 lines changed or deleted | | 3 lines changed or added | |
|
| TableImpl.hpp | | TableImpl.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 25 | | skipping to change at line 25 | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_TABLE_IMPL_HPP | | #ifndef RAUL_TABLE_IMPL_HPP | |
| #define RAUL_TABLE_IMPL_HPP | | #define RAUL_TABLE_IMPL_HPP | |
| | | | |
| #include <cassert> | | #include <cassert> | |
| #include <stdexcept> | | #include <stdexcept> | |
| #include <algorithm> | | #include <algorithm> | |
| #include <iostream> | | #include <iostream> | |
|
| #include <raul/Table.hpp> | | #include "raul/Table.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
| /* FIXME: This could be a lot less code... */ | | /* FIXME: This could be a lot less code... */ | |
| | | | |
| #ifdef TABLE_SORT_DEBUG | | #ifdef TABLE_SORT_DEBUG | |
| template <typename K, typename T> | | template <typename K, typename T> | |
| bool | | bool | |
| Table<K,T>::is_sorted() const | | Table<K,T>::is_sorted() const | |
| { | | { | |
| | | | |
| skipping to change at line 147 | | skipping to change at line 147 | |
| Table<K,T>::find_range_end(iterator start, bool (*comp)(const K&,const K&)) | | Table<K,T>::find_range_end(iterator start, bool (*comp)(const K&,const K&)) | |
| { | | { | |
| if (size() == 0 || start == end()) | | if (size() == 0 || start == end()) | |
| return this->end(); | | return this->end(); | |
| | | | |
| const K& key = start->first; | | const K& key = start->first; | |
| | | | |
| size_t lower = start._index; | | size_t lower = start._index; | |
| size_t upper = size() - 1; | | size_t upper = size() - 1; | |
| | | | |
|
| if (lower == upper) | | if (lower == upper) { | |
| if (comp(key, _entries[lower].first)) | | if (comp(key, _entries[lower].first)) | |
| return iterator(*this, lower+1); | | return iterator(*this, lower+1); | |
| else | | else | |
| return this->end(); | | return this->end(); | |
|
| | | } | |
| | | | |
| size_t i; | | size_t i; | |
| | | | |
| while (upper > lower) { | | while (upper > lower) { | |
| | | | |
| i = lower + ((upper - lower) / 2); | | i = lower + ((upper - lower) / 2); | |
| | | | |
|
| if (upper - lower == 1) | | if (upper - lower == 1) { | |
| if (comp(key, _entries[upper].first) && upper < size
()) | | if (comp(key, _entries[upper].first) && upper < size
()) | |
| return iterator(*this, upper+1); | | return iterator(*this, upper+1); | |
| else if (lower < size()) | | else if (lower < size()) | |
| return iterator(*this, lower+1); | | return iterator(*this, lower+1); | |
|
| | | } | |
| | | | |
| const Entry& elem = _entries[i]; | | const Entry& elem = _entries[i]; | |
| | | | |
| // Hit | | // Hit | |
| if (comp(key, elem.first)) { | | if (comp(key, elem.first)) { | |
| | | | |
| if (i == size()-1 || !comp(key, _entries[i+1].first)
) | | if (i == size()-1 || !comp(key, _entries[i+1].first)
) | |
| return iterator(*this, i+1); | | return iterator(*this, i+1); | |
| else | | else | |
| lower = i; | | lower = i; | |
| | | | |
| skipping to change at line 262 | | skipping to change at line 264 | |
| * O(n) worst case | | * O(n) worst case | |
| * O(log(n)) best case (capacity is large enough) | | * O(log(n)) best case (capacity is large enough) | |
| */ | | */ | |
| template <typename K, typename T> | | template <typename K, typename T> | |
| std::pair<typename Table<K,T>::iterator, bool> | | std::pair<typename Table<K,T>::iterator, bool> | |
| Table<K,T>::insert(const std::pair<K, T>& entry) | | Table<K,T>::insert(const std::pair<K, T>& entry) | |
| { | | { | |
| const K& key = entry.first; | | const K& key = entry.first; | |
| const T& value = entry.second; | | const T& value = entry.second; | |
| | | | |
|
| if (size() == 0 || size() == 1 && key > _entries[0].first) { | | if (size() == 0 || (size() == 1 && key > _entries[0].first)) { | |
| _entries.push_back(entry); | | _entries.push_back(entry); | |
| return std::make_pair(iterator(*this, size()-1), true); | | return std::make_pair(iterator(*this, size()-1), true); | |
| } else if (size() == 1) { | | } else if (size() == 1) { | |
| _entries.push_back(_entries[0]); | | _entries.push_back(_entries[0]); | |
| _entries[0] = entry; | | _entries[0] = entry; | |
| return std::make_pair(begin(), true); | | return std::make_pair(begin(), true); | |
| } | | } | |
| | | | |
| size_t lower = 0; | | size_t lower = 0; | |
| size_t upper = size() - 1; | | size_t upper = size() - 1; | |
| | | | |
End of changes. 7 change blocks. |
| 5 lines changed or deleted | | 7 lines changed or added | |
|
| Thread.hpp | | Thread.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 91 | | skipping to change at line 91 | |
| | | | |
| inline static void* _static_run(void* me) { | | inline static void* _static_run(void* me) { | |
| pthread_setspecific(_thread_key, me); | | pthread_setspecific(_thread_key, me); | |
| Thread* myself = (Thread*)me; | | Thread* myself = (Thread*)me; | |
| myself->_run(); | | myself->_run(); | |
| myself->_pthread_exists = false; | | myself->_pthread_exists = false; | |
| return NULL; // and I | | return NULL; // and I | |
| } | | } | |
| | | | |
| /** Allocate thread-specific data key */ | | /** Allocate thread-specific data key */ | |
|
| static void thread_key_alloc() | | static void thread_key_alloc() { | |
| { | | | |
| pthread_key_create(&_thread_key, NULL); | | pthread_key_create(&_thread_key, NULL); | |
| } | | } | |
| | | | |
| /* Key for the thread-specific buffer */ | | /* Key for the thread-specific buffer */ | |
| static pthread_key_t _thread_key; | | static pthread_key_t _thread_key; | |
| | | | |
| /* Once-only initialisation of the key */ | | /* Once-only initialisation of the key */ | |
| static pthread_once_t _thread_key_once; | | static pthread_once_t _thread_key_once; | |
| | | | |
| unsigned _context; | | unsigned _context; | |
| std::string _name; | | std::string _name; | |
| bool _pthread_exists; | | bool _pthread_exists; | |
|
| | | bool _own_thread; | |
| pthread_t _pthread; | | pthread_t _pthread; | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_THREAD_HPP | | #endif // RAUL_THREAD_HPP | |
| | | | |
End of changes. 3 change blocks. |
| 3 lines changed or deleted | | 3 lines changed or added | |
|
| TimeSlice.hpp | | TimeSlice.hpp | |
| /* This file is part of Raul. | | /* This file is part of Raul. | |
|
| * Copyright (C) 2007 Dave Robillard <http://drobilla.net> | | * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net> | |
| * | | * | |
| * Raul is free software; you can redistribute it and/or modify it under th
e | | * Raul is free software; you can redistribute it and/or modify it under th
e | |
| * terms of the GNU General Public License as published by the Free Softwar
e | | * terms of the GNU General Public License as published by the Free Softwar
e | |
| * Foundation; either version 2 of the License, or (at your option) any lat
er | | * Foundation; either version 2 of the License, or (at your option) any lat
er | |
| * version. | | * version. | |
| * | | * | |
| * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | | * Raul is distributed in the hope that it will be useful, but WITHOUT ANY | |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNES
S | |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for detail
s. | |
| * | | * | |
| | | | |
| skipping to change at line 24 | | skipping to change at line 24 | |
| * with this program; if not, write to the Free Software Foundation, Inc., | | * with this program; if not, write to the Free Software Foundation, Inc., | |
| * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | | */ | |
| | | | |
| #ifndef RAUL_TIME_SLICE_HPP | | #ifndef RAUL_TIME_SLICE_HPP | |
| #define RAUL_TIME_SLICE_HPP | | #define RAUL_TIME_SLICE_HPP | |
| | | | |
| #include <cassert> | | #include <cassert> | |
| #include <cmath> | | #include <cmath> | |
| #include <boost/utility.hpp> | | #include <boost/utility.hpp> | |
|
| #include <raul/types.hpp> | | #include "raul/TimeStamp.hpp" | |
| | | | |
| namespace Raul { | | namespace Raul { | |
| | | | |
|
| | | /* FIXME: all the conversion here is wrong now */ | |
| | | | |
| /** A duration of time, with conversion between tick time and beat time. | | /** A duration of time, with conversion between tick time and beat time. | |
| * | | * | |
| * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beat
s | | * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beat
s | |
| * are equal). Relation to an external time base (e.g. Jack frame time) is | | * are equal). Relation to an external time base (e.g. Jack frame time) is | |
| * represented by frame_offset (the idea is that this holds all the informa
tion | | * represented by frame_offset (the idea is that this holds all the informa
tion | |
| * necessary for passing to run() methods so they know the current state of | | * necessary for passing to run() methods so they know the current state of | |
| * things WRT time). | | * things WRT time). | |
| * | | * | |
| * This class handles conversion between two units of time: musical | | * This class handles conversion between two units of time: musical | |
| * (beat) time, and real (tick) time. Real time is discrete, the smallest | | * (beat) time, and real (tick) time. Real time is discrete, the smallest | |
| * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat t
ime | | * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat t
ime | |
| * is stored as a double (to be independent of any rates or timer precision
). | | * is stored as a double (to be independent of any rates or timer precision
). | |
| * | | * | |
| * This caches as many values as possible to make calls less expensive, pas
s it | | * This caches as many values as possible to make calls less expensive, pas
s it | |
| * around by reference, not value. | | * around by reference, not value. | |
| * | | * | |
| * \ingroup raul | | * \ingroup raul | |
| */ | | */ | |
| class TimeSlice : public boost::noncopyable { | | class TimeSlice : public boost::noncopyable { | |
| public: | | public: | |
|
| TimeSlice(double tick_rate, double bpm) | | TimeSlice(uint32_t rate, uint32_t ppqn, double bpm) | |
| : _tick_rate(tick_rate) | | : _tick_rate(rate) | |
| , _beat_rate(60.0/bpm) | | , _beat_rate(60.0/bpm) | |
|
| , _start_ticks(0) | | , _start_ticks(Raul::TimeUnit(Raul::TimeUnit::FRAMES, rate), | |
| , _length_ticks(0) | | 0, 0) | |
| , _start_beats(0) | | , _length_ticks(TimeUnit(TimeUnit::FRAMES, rate), 0, 0) | |
| , _length_beats(0) | | , _start_beats(TimeUnit(TimeUnit::BEATS, ppqn), 0, 0) | |
| , _offset_ticks(0) | | , _length_beats(TimeUnit(TimeUnit::BEATS, ppqn), 0, 0) | |
| | | , _offset_ticks(TimeUnit(TimeUnit::FRAMES, rate), 0, 0) | |
| {} | | {} | |
| | | | |
| /** Set the start and length of the slice. | | /** Set the start and length of the slice. | |
| * | | * | |
| * Note that external offset is not affected by this, don't forget t
o reset | | * Note that external offset is not affected by this, don't forget t
o reset | |
| * the offset each cycle! | | * the offset each cycle! | |
| */ | | */ | |
|
| void set_window(TickTime start, TickCount length) { | | void set_slice(TimeStamp start, TimeDuration length) { | |
| | | assert(start.unit() == ticks_unit()); | |
| | | assert(length.unit() == ticks_unit()); | |
| _start_ticks = start; | | _start_ticks = start; | |
| _length_ticks = length; | | _length_ticks = length; | |
| update_beat_time(); | | update_beat_time(); | |
| } | | } | |
| | | | |
|
| void set_start(TickTime time) { _start_ticks = time; update_beat_tim | | void set_length(TimeDuration length) { | |
| e(); } | | assert(length.unit() == ticks_unit()); | |
| | | _length_ticks = length; | |
| void set_length(TickCount length) { _length_ticks = length; update_b | | _length_beats = ticks_to_beats(_length_ticks); | |
| eat_time(); } | | } | |
| | | | |
|
| bool contains(TickTime time) { | | bool contains(TimeStamp time) { | |
| return (time >= start_ticks() && time < start_ticks() + leng
th_ticks()); | | return (time >= start_ticks() && time < start_ticks() + leng
th_ticks()); | |
| } | | } | |
| | | | |
| double tick_rate() { return _tick_rate; } | | double tick_rate() { return _tick_rate; } | |
| double beat_rate() { return _beat_rate; } | | double beat_rate() { return _beat_rate; } | |
| double bpm() { return 60/_beat_rate; } | | double bpm() { return 60/_beat_rate; } | |
| | | | |
| void set_tick_rate(double tick_rate) { | | void set_tick_rate(double tick_rate) { | |
| _tick_rate = tick_rate; | | _tick_rate = tick_rate; | |
| update_beat_time(); | | update_beat_time(); | |
| } | | } | |
| | | | |
| void set_bpm(double bpm) { | | void set_bpm(double bpm) { | |
| _beat_rate = 60.0/bpm; | | _beat_rate = 60.0/bpm; | |
| update_beat_time(); | | update_beat_time(); | |
| } | | } | |
| | | | |
|
| inline Seconds beats_to_seconds(BeatTime beats) const { | | inline TimeStamp beats_to_seconds(TimeStamp beats) const { | |
| return (beats * _beat_rate); | | return TimeStamp(real_unit(), beats.to_double() * 1/(double) | |
| | | _beat_rate); | |
| } | | } | |
| | | | |
|
| inline TickTime beats_to_ticks(BeatTime beats) const { | | inline TimeStamp beats_to_ticks(TimeStamp beats) const { | |
| return static_cast<TickTime>(floor(beats_to_seconds(beats) / | | return TimeStamp(ticks_unit(), beats.to_double() / (double)_ | |
| _tick_rate)); | | beat_rate * _tick_rate); | |
| } | | } | |
| | | | |
|
| inline Seconds ticks_to_seconds(TickTime ticks) const { | | inline TimeStamp ticks_to_seconds(TimeStamp ticks) const { | |
| return (ticks * _tick_rate); | | return TimeStamp(real_unit(), ticks.ticks() * 1/(double)_tic | |
| | | k_rate); | |
| } | | } | |
| | | | |
|
| inline BeatTime ticks_to_beats(TickTime ticks) const { | | inline TimeStamp ticks_to_beats(TimeStamp ticks) const { | |
| return ticks_to_seconds(ticks) / _beat_rate; | | return TimeStamp(beats_unit(), ticks.ticks() * 1/(double)_ti | |
| | | ck_rate * _beat_rate); | |
| } | | } | |
| | | | |
| /** Start of current sub-cycle in ticks */ | | /** Start of current sub-cycle in ticks */ | |
|
| inline TickTime start_ticks() const { return _start_ticks; } | | inline TimeStamp start_ticks() const { return _start_ticks; } | |
| | | | |
| /** Length of current sub-cycle in ticks */ | | /** Length of current sub-cycle in ticks */ | |
|
| inline TickCount length_ticks() const { return _length_ticks; } | | inline TimeDuration length_ticks() const { return _length_ticks; } | |
| | | | |
| /** Start of current sub-cycle in beats */ | | /** Start of current sub-cycle in beats */ | |
|
| inline BeatTime start_beats() const { return _start_beats; } | | inline TimeStamp start_beats() const { return _start_beats; } | |
| | | | |
| /** Length of current sub-cycle in beats */ | | /** Length of current sub-cycle in beats */ | |
|
| inline BeatCount length_beats() const { return _length_beats; } | | inline TimeDuration length_beats() const { return _length_beats; } | |
| | | | |
| /** Set the offset between real-time and timeslice-time. */ | | /** Set the offset between real-time and timeslice-time. */ | |
|
| inline void set_offset(TickCount offset) { _offset_ticks = offset; } | | inline void set_offset(TimeDuration offset) { _offset_ticks = offset
; } | |
| | | | |
| /** Offset relative to external (e.g Jack) time */ | | /** Offset relative to external (e.g Jack) time */ | |
|
| inline TickCount offset_ticks() const { return _offset_ticks; } | | inline TimeDuration offset_ticks() const { return _offset_ticks; } | |
| | | | |
|
| private: | | inline TimeUnit beats_unit() const { return _start_beats.unit(); } | |
| | | inline TimeUnit ticks_unit() const { return _start_ticks.unit(); } | |
| | | inline TimeUnit real_unit() const { return TimeUnit(TimeUnit::SECON | |
| | | DS, 0); } | |
| | | | |
|
| | | private: | |
| inline void update_beat_time() { | | inline void update_beat_time() { | |
| _start_beats = ticks_to_beats(_start_ticks); | | _start_beats = ticks_to_beats(_start_ticks); | |
| _length_beats = ticks_to_beats(_length_ticks); | | _length_beats = ticks_to_beats(_length_ticks); | |
| } | | } | |
| | | | |
| // Rate/Tempo | | // Rate/Tempo | |
| double _tick_rate; ///< Tick rate in Hz (e.g. sample rate) | | double _tick_rate; ///< Tick rate in Hz (e.g. sample rate) | |
| double _beat_rate; ///< Beat rate in Hz | | double _beat_rate; ///< Beat rate in Hz | |
| | | | |
| // Current time | | // Current time | |
|
| TickTime _start_ticks; ///< Current window start in ticks | | TimeStamp _start_ticks; ///< Current window start in ticks | |
| TickCount _length_ticks; ///< Current window length in ticks | | TimeDuration _length_ticks; ///< Current window length in ticks | |
| BeatTime _start_beats; ///< Current window start in beats | | TimeStamp _start_beats; ///< Current window start in beats | |
| BeatCount _length_beats; ///< Current window length in beats | | TimeDuration _length_beats; ///< Current window length in beats | |
| | | | |
|
| TickCount _offset_ticks; ///< Offset to global time (ie Jack sub-cyc
le offset) | | TimeDuration _offset_ticks; ///< Offset to global time (ie Jack sub-
cycle offset) | |
| }; | | }; | |
| | | | |
| } // namespace Raul | | } // namespace Raul | |
| | | | |
| #endif // RAUL_TIME_SLICE_HPP | | #endif // RAUL_TIME_SLICE_HPP | |
| | | | |
End of changes. 22 change blocks. |
| 37 lines changed or deleted | | 49 lines changed or added | |
|