jack c++ API
Moderators: MattKingUSA, khz
jack c++ API
is there no standard C++ API for JACK that people use?
i found this which is 2 years old as well as what appears to be an API by male. I thought a lot of LAU apps are written in C++, do people just use the C headers and drudge their own way to success?
( also how do I post to LAD? I tried posting a couple months ago but I never saw my message or any responses. Nabble has it though. )
i found this which is 2 years old as well as what appears to be an API by male. I thought a lot of LAU apps are written in C++, do people just use the C headers and drudge their own way to success?
( also how do I post to LAD? I tried posting a couple months ago but I never saw my message or any responses. Nabble has it though. )
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
The problem is that C++ has no stable ABI so people still use C ABI to talk between programs. I plan to provide C++14 wrapper too.
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
Why do you need C++ API for such simple-interfaced things like JACK?tatch wrote:is there no standard C++ API for JACK that people use?
JACK's C interface is well designed, well documented and intuitively understandable.
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
C and C++ are very different languages with very different idioms. C APIs can't provide RAII, exceptions and other things you normally expect from any decent C++ API. In my experience I've never used C API directly in my C++ code. I always make a wrapper.sadko4u wrote:Why do you need C++ API for such simple-interfaced things like JACK?
By the way, I've looked at the source code of those libraries and they're written in C++03 which is very outdated now. People don't write code like this these days.
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
Oh no, you really need for simple things like JACK API such piece of crap like RAII, exceptions and huge causeless metaprogramming?FaTony wrote:C and C++ are very different languages with very different idioms. C APIs can't provide RAII, exceptions and other things you normally expect from any decent C++ API.sadko4u wrote:Why do you need C++ API for such simple-interfaced things like JACK?
It's normal to wrap functions into object-oriented code. And it's normal that for different tasks different wrappers can be implemented. So I think, topic starter should better write his own wrapper.FaTony wrote:In my experience I've never used C API directly in my C++ code. I always make a wrapper.
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
Maybe you need to read tutorials from this century?sadko4u wrote:Oh no, you really need for simple things like JACK API such piece of crap like RAII, exceptions and huge causeless metaprogramming?
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
I follow the changes that are made in C++ since C++98 and can say that things have changed not particularly better.FaTony wrote:Maybe you need to read tutorials from this century?
There is still no normal RTTI and no reflection.
There is still no FINALLY statement because C++ language designers propagate RAII concept that isn't a magic pill in most cases. Yes, now it can be emulated with lambdas but without macros (which 'are hell', as said by Stroustroup) it will look out like a crap.
Exceptions and pointers can not be safely combined together without auto_ptr. You could avoid pointer metaprogramming by using finally but... you already know.
Break from nested loop? No, we still don't have this facility, we must use flag variables or goto (which 'is hell').
Oh yes! Now we got 'auto' keyword that allows us not to write the full 10-meter type name of the variable. But this does not fix that fact that C++ has a very complicated type system, and after changes made in C++11 that extend metaprogramming it will have even more complicated type system. I still can not pass std::vector<char *> to the function that requires std::vector<const char *> as argument. Instead of this I have to do a copy of the collection and pass it. And I still get many-many lines of the compiler's error output when I pass something non-natural to the STL's container template argument.
Operator overloading makes each expression non-obvious and context-specific, so without additional syntax highliting and code inspection you can not actually say what does expression 'c=a+b' mean.
For these and many other facts I decided to use C++ for my project only as 'C with classes'. Instead of catching std::bad_alloc (that nobody catches in 95% of project, even in STL code there is no out-of-memory control) in many places I prefer to turn-off exception handling and check pointer for non-NULL value because when the code falls on an unhandled exception, we can not get stack trace of the exception to find the actual place where it was thrown, so dereferencing of NULL pointer is better. I do not use STL because it generates huge amount of machine code for each new template instance and because C++ does non-wanted inlining of generated code where you don't want this. That's why I avoid templates where it's possible. And actually in 99% of cases you really do not need templates.
So if I can use C API, I use it directly without any wrappers. If I need this API on some instance in more than one place, I write a simple wrapping class without RAII, exceptions and other together-conflicting factilities of C++.
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
Define "normal RTTI". I have no problems with current RTTI.sadko4u wrote:There is still no normal RTTI and no reflection.
There is zero need for "finally" precisely because of RAII. If your classes don't follow RAII then you are doing it wrong.sadko4u wrote:There is still no FINALLY statement because C++ language designers propagate RAII concept that isn't a magic pill in most cases.
Combined? What? auto_ptr was deprecated in C++11. Now we have unique_ptr and shared_ptr. What do you mean by "pointer metaprogramming"? Again, there's no need for "finally" because smart pointers follow RAII and raw pointers are presumed non-owning. If you have owning raw pointers, you're doing it wrong.sadko4u wrote:Exceptions and pointers can not be safely combined together without auto_ptr. You could avoid pointer metaprogramming by using finally but... you already know.
C doesn't have it too. Name the language that has this.sadko4u wrote:Break from nested loop? No, we still don't have this facility, we must use flag variables or goto (which 'is hell').
char* is a C legacy. You need to pass std::vector<std::string>.sadko4u wrote:I still can not pass std::vector<char *> to the function that requires std::vector<const char *> as argument.
Every tool can be abused. If you find a library that makes the code ambiguous, find a better library.sadko4u wrote:Operator overloading makes each expression non-obvious and context-specific, so without additional syntax highliting and code inspection you can not actually say what does expression 'c=a+b' mean.
Just as I expected. You just couldn't learn proper C++. Maybe all you read was Russian books? I've read a couple of them and they were total shit.sadko4u wrote:For these and many other facts I decided to use C++ for my project only as 'C with classes'. Instead of catching std::bad_alloc (that nobody catches in 95% of project, even in STL code there is no out-of-memory control) in many places I prefer to turn-off exception handling and check pointer for non-NULL value because when the code falls on an unhandled exception, we can not get stack trace of the exception to find the actual place where it was thrown, so dereferencing of NULL pointer is better. I do not use STL because it generates huge amount of machine code for each new template instance and because C++ does non-wanted inlining of generated code where you don't want this. That's why I avoid templates where it's possible. And actually in 99% of cases you really do not need templates.
So if I can use C API, I use it directly without any wrappers. If I need this API on some instance in more than one place, I write a simple wrapping class without RAII, exceptions and other together-conflicting factilities of C++.
Guess what, all my classes follow RAII, I never use error codes and always use exceptions, and about ~70% of all my code is templates. I've even written a digital audio processing library that is 99% templates. The only non-template part is reading and writing WAV files. Why? Because templates allow you to work with any type. In my library almost all class templates take sample type and allocator so all my classes templates work with any bit depth and allocator. Want 16, 24, 32 bit int? Supported out of the box. Want 64 bit int and 128 bit float? Write a 100 line class and the whole library suddenly supports it.
I personally hate C because of it's raw pointers, arrays and strings and because it doesn't have templates and RAII. Whenever I see the code which says "but then you need to call this function to clean this up", I'm like "O rly? Gotta find a better API". But I'm pretty sure C will die in about 50 years and we'll have a much better languages.
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
Normal RTTI means reflection. It means that I can take the pointer to the object and get ALL information about structure of it's type and, also, can dynamically find and call methods of this object by name and argument types. C++'s RTTI is a fake.FaTony wrote:Define "normal RTTI". I have no problems with current RTTI.
RAII is not a magic pillow. C++ provides many duplicate facilities (pointers and references, macroses and templates, classes and structures). Programming with RAII input/output and interaction between processes is like shooting into leg. Finally allows to do code smarter and more predictive than using huge amount of wrapping classes instead of one that internally uses 'finally' statements. С++ adepts get cranky on RAII and write huge amount of templated code there where they just could insert 'finally'. If C++ is so 'flexible' and 'powerful', why it does not provide such 'duplicate to RAII facility' like 'finally'? Also RAII is poor ideology because... C++'s destructors can not throw exceptions (no, they can but it's very dangerous)! So to properly free/destruct resource I still should call special destroying routine before issuing the destructor or write tons of code that allow to pass error from destrutor to the environment. So in this case all usage of RAII goes to epic fail because I spend a lot of time by writing code that I shouldn't write if I used 'finally'.FaTony wrote:There is zero need for "finally" precisely because of RAII. If your classes don't follow RAII then you are doing it wrong.
So this thing I directly mean. Now instead of auto_ptr we should use two type of template wrappers: unique_ptr and shared_ptr. And they have additional overhead of data and restrictions (still relative to RAII!).FaTony wrote:Combined? What? auto_ptr was deprecated in C++11. Now we have unique_ptr and shared_ptr. What do you mean by "pointer metaprogramming"?
For C it's normal because it does not have constructors/destructors, templates and other 'special' memory and resource management. C is designed so that it allows simply translate it's code into assembly code in mind and vice verse. Stroustroup called 'goto' statement 'evil' but didn't provide something for replacement.FaTony wrote:C doesn't have it too. Name the language that has this.
Languages that allow 'break out the nested loop': Java, JavaScript, C#, D and even PERL.
Even more. I can't pass std::vector<std::string> to the function that requires std::vector<const std::string>. Replacing char * to std::string does not solve the problem.FaTony wrote:char* is a C legacy. You need to pass std::vector<std::string>.
You're wrong because C++ adepts say 'only this way is right' by providing such crap libraries like STL and Boost. I saw how one C++ adept tried to perform multithreaded IO on sockets with new libraries provided by C++ 11 standard. I couldn't read his code without many facepalms because there were a lot of hacks that could be avoided by just writing raw C-style code.FaTony wrote:Every tool can be abused. If you find a library that makes the code ambiguous, find a better library.
I've read Stroustroup's third edition book many years ago and wanted to be employeed as C++ developer. But, fortunately, PERL and JAVA was offered to me instead. Also I'm highly experienced in writing low-level assembly code. So I have a good base to perform comparison.FaTony wrote:Just as I expected. You just couldn't learn proper C++. Maybe all you read was Russian books?
This?FaTony wrote: Guess what, all my classes follow RAII, I never use error codes and always use exceptions, and about ~70% of all my code is templates. I've even written a digital audio processing library that is 99% templates.
The only non-template part is reading and writing WAV files. Why? Because templates allow you to work with any type. In my library almost all class templates take sample type and allocator so all my classes templates work with any bit depth and allocator. Want 16, 24, 32 bit int? Supported out of the box. Want 64 bit int and 128 bit float? Write a 100 line class and the whole library suddenly supports it.
Code: Select all
stream.Read(chunkid.data(), chunkid.size());
stream >> chunksize;
if (chunkid == FormatChunkID)
{
// Format chunk.
stream >> format;
stream >> numchannels;
stream >> samplerate;
std::uint32_t byterate;
stream >> byterate;
stream >> blockalign;
stream >> bitdepth;
if (chunksize == 16)
{
continue;
}
std::uint16_t extensionsize;
stream >> extensionsize;
// Skip extension bytes for now.
stream.SeekReadPosition(extensionsize, std::ios_base::cur);
}
Code: Select all
template <typename T, typename Allocator>
void Pan<T, Allocator>::Render(MultichannelAudioBuffer<T, Allocator>& buffer)
{
if (buffer.GetNumberOfChannels() == 1)
{
buffer.ChannelPushBack(buffer[0].GetAudioBuffer());
}
else if (buffer.GetNumberOfChannels() != 2)
{
throw std::invalid_argument{"Pan::Render: Invalid number of channels."};
}
buffer[0] += leftgain;
buffer[1] += rightgain;
}
Code: Select all
template <typename T, typename Allocator>
AmplifierMIDIControl<T, Allocator>::AmplifierMIDIControl(
Amplifier<T, Allocator>& amp, MIDI::InputChannel& channel,
Gain<CalcType> maxgain)
: amp{amp}, channel{channel}, maxgain{std::move(maxgain)}
{
cchook = channel.HookControlChange([&](const auto& event){
this->OnControlChange(event); });
this->SetGain();
}
1. You have a lot of code overhead for processing one sample. For simple devices it's not noticeable. For devices that do complex processing it's a very huge performance penalty. Yes, it looks funny but doesn't solve the more foreground task: it should be fast as possible.
2. For audio processing on very popular x86 architecture float and double are enough to do many things. You do not need to support many sample formats.
3. The behaviour of fixed-point is very different to floating point, especially relative to overflows/undeflows. So you will be forced to completely rewrite your code for microcontrollers also for performance purposes.
And this is is reasonalbe. All your RAII is powerless when the cleaning function takes a lot of time for execution or returns error code. When you use auto-destruction wrappers, you can not properly handle the behaviour of your code relative to long cleaning. Also you can not throw exceptions from destructors, surprise!Whenever I see the code which says "but then you need to call this function to clean this up", I'm like "O rly?
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
This would mean having lots of runtime overhead to store reflection info. But if you really want it, why not to make a proposal to ISO committee.sadko4u wrote:Normal RTTI means reflection. It means that I can take the pointer to the object and get ALL information about structure of it's type and, also, can dynamically find and call methods of this object by name and argument types. C++'s RTTI is a fake.
Because of the C compatibility. Yeah, I would love to get rid of pointers and macros.sadko4u wrote:RAII is not a magic pillow. C++ provides many duplicate facilities (pointers and references, macroses and templates, classes and structures).
You can spent 5 minutes of your time and have a "finally" class template.sadko4u wrote:Programming with RAII input/output and interaction between processes is like shooting into leg. Finally allows to do code smarter and more predictive than using huge amount of wrapping classes instead of one that internally uses 'finally' statements. С++ adepts get cranky on RAII and write huge amount of templated code there where they just could insert 'finally'. If C++ is so 'flexible' and 'powerful', why it does not provide such 'duplicate to RAII facility' like 'finally'?
If cleanup function fails, you can't do anything except logging an error and terminating the application which you can do using destructor.sadko4u wrote:Also RAII is poor ideology because... C++'s destructors can not throw exceptions (no, they can but it's very dangerous)! So to properly free/destruct resource I still should call special destroying routine before issuing the destructor or write tons of code that allow to pass error from destrutor to the environment. So in this case all usage of RAII goes to epic fail because I spend a lot of time by writing code that I shouldn't write if I used 'finally'.
unique_ptr has zero overhead. shared_ptr has reference count because it's supposed to be shared. You use shared_ptr only if you really need it.sadko4u wrote:So this thing I directly mean. Now instead of auto_ptr we should use two type of template wrappers: unique_ptr and shared_ptr. And they have additional overhead of data and restrictions (still relative to RAII!).
I have never seen a library where template parameter is const. Library that uses std::vector<const std::string> is brain dead.sadko4u wrote:Even more. I can't pass std::vector<std::string> to the function that requires std::vector<const std::string>. Replacing char * to std::string does not solve the problem.
STL and Boost are crap? Look at the header of it's site:sadko4u wrote:You're wrong because C++ adepts say 'only this way is right' by providing such crap libraries like STL and Boost.
Herb Sutter is the head of ISO C++ standardization committee. If you would compare his opinion and another from some random guy on the Internet, I would certainly choose the first one."...one of the most highly regarded and expertly designed C++ library projects in the world." — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards
Another point: STL was written in 1994 and became a basis of the part of the C++ standard library. There are zero occurrences of the word "STL" in the standard. To me, STL is Stephan T Lavavej.
Where have you found an overhead?sadko4u wrote:This?Or this?Code: Select all
snip
Or this?Code: Select all
snip
Sorry, but for audio processing it's a holy crap. Because:Code: Select all
snip
1. You have a lot of code overhead for processing one sample.
I convert to float for processing. And unlike your design, I give user the choice of their preferred bit depth.sadko4u wrote:2. For audio processing on very popular x86 architecture float and double are enough to do many things. You do not need to support many sample formats.
There is no fixed point types in ISO C++ and I'm not interested in platform specific hacks.sadko4u wrote:3. The behaviour of fixed-point is very different to floating point, especially relative to overflows/undeflows. So you will be forced to completely rewrite your code for microcontrollers also for performance purposes.
Again, if cleanup fails, you can't fix it. If cleanup takes much time you too can't do anything to make it faster.sadko4u wrote:And this is is reasonalbe. All your RAII is powerless when the cleaning function takes a lot of time for execution or returns error code. When you use auto-destruction wrappers, you can not properly handle the behaviour of your code relative to long cleaning. Also you can not throw exceptions from destructors, surprise!
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
I've already solved this by using macros (which are 'evil') and lambas. Syntax changed but still comfortable for use, without need of huge typing:FaTony wrote:You can spent 5 minutes of your time and have a "finally" class template.
Code: Select all
template<typename T>
class _ddb_finalizer
{
private:
T _f;
public:
inline _ddb_finalizer( const T f ): _f(f) { };
inline ~_ddb_finalizer() { _f(); };
};
template<typename T>
_ddb_finalizer<T> _ddb_finalizer_inst( const T x )
{
return _ddb_finalizer<T>(x);
};
#define __FINALLY_IMPL(line, code) auto _ddb_finalizer_var##line = _ddb_finalizer_inst( [&]() { code; } );
#define __FINALLY_PROXY(line, code) __FINALLY_IMPL(line, code)
#define FINALLY(code) __FINALLY_PROXY(__LINE__, code)
#include <stdio.h>
int main()
{
printf("init\n");
int *p = new int[100];
FINALLY
(
printf("cleanup\n");
if (p != NULL)
delete [] p;
);
printf("some code\n");
}
Terminating application? You're serious? I should terminate application on probabale I/O error with sockets or filesystem? No, instead of this I can launch some process for fixing the problem or retry some amount of I/O operations. But this all requires some time, so the problem object/resource should be passed to another cleaning/fixing thread.FaTony wrote:If cleanup function fails, you can't do anything except logging an error and terminating the application which you can do using destructor.
Really? And what about tuples? /usr/include/c++/4.8/bits/unique_ptr.h:FaTony wrote: unique_ptr has zero overhead.
Code: Select all
/// 20.7.1.2 unique_ptr for single objects.
template <typename _Tp, typename _Dp = default_delete<_Tp> >
class unique_ptr
{
// ...
typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
__tuple_type _M_t;
// ...
Oh really? Let's look into /usr/include/c++/4.8/bits/shared_ptr.h and included files:FaTony wrote:shared_ptr has reference count because it's supposed to be shared. You use shared_ptr only if you really need it.
Code: Select all
template<>
class _Mutex_base<_S_mutex>
: public __gnu_cxx::__mutex
{
protected:
// This policy is used when atomic builtins are not available.
// The replacement atomic operations might not have the necessary
// memory barriers.
enum { _S_need_barriers = 1 };
};
//...
template<_Lock_policy _Lp = __default_lock_policy>
class _Sp_counted_base
: public _Mutex_base<_Lp>
{
// ...
private:
//...
_Atomic_word _M_use_count; // #shared
_Atomic_word _M_weak_count; // #weak + (#shared != 0)
};
template<_Lock_policy _Lp>
class __shared_count
{
// ...
_Sp_counted_base<_Lp>* _M_pi;
};
template<typename _Tp, _Lock_policy _Lp>
class __shared_ptr
{
// ...
_Tp* _M_ptr; // Contained pointer.
__shared_count<_Lp> _M_refcount; // Reference counter.
};
// from namespace __gnu_cxx:
class __mutex
{
private:
#if __GTHREADS && defined __GTHREAD_MUTEX_INIT
__gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT;
#else
__gthread_mutex_t _M_mutex;
#endif
//...
};
Really? So you pass std::vector<std::string> to the function in hope that it won't modify strings from passed vector? This is called 'not brain dead'?FaTony wrote:I have never seen a library where template parameter is const. Library that uses std::vector<const std::string> is brain dead.
I can give another site that says contrary things. Don't try to citate somebody, give facts.FaTony wrote: STL and Boost are crap? Look at the header of it's site:
As the counterpart I can add that there is currently no C++ provided without STL. From STL we get damn std::cout, std::cin and many other unusable stuff.FaTony wrote:Another point: STL was written in 1994 and became a basis of the part of the C++ standard library. There are zero occurrences of the word "STL" in the standard.
Oh, sorry, I thought it was shit. But now I see it is a complete shit:FaTony wrote: Where have you found an overhead?
Code: Select all
/// \brief Amplifies all samples by the given gain.
/// \param[in] gain Gain to apply.
/// \return Reference to this audio buffer.
MultichannelAudioBuffer& operator+=(Gain<CalcType> gain);
/// \brief Adds the given value to all samples.
/// \param[in] value Value to add.
/// \return Reference to this audio buffer.
MultichannelAudioBuffer& operator+=(typename T::ValueType value);
template <typename T, typename Allocator>
MultichannelAudioBuffer<T, Allocator>& MultichannelAudioBuffer<T, Allocator>::
operator+=(Gain<CalcType> gain)
{
for (auto&& channel : channels)
{
channel += gain;
}
return *this;
}
template <typename T, typename Allocator> template <bool IsConst>
typename MultichannelAudioBuffer<T, Allocator>::
template FrameReference<IsConst>& MultichannelAudioBuffer<T, Allocator>::
FrameReference<IsConst>::operator+=(Gain<CalcType> gain)
{
for (auto&& sample : buffer)
{
*sample += gain;
}
return *this;
}
template <typename T, typename CT>
Sample<T, CT>& Sample<T, CT>::operator+=(Gain<CalcType> gain)
{
return *this *= gain.GetValue();
}
template <typename CalcType>
CalcType Gain<CalcType>::GetValue(void) const
{
return value;
}
Or you can simply provide two overloaded functions that do same things in bulk mode with specified size of float instead of building huge template structure.FaTony wrote:I convert to float for processing. And unlike your design, I give user the choice of their preferred bit depth.
Under fixed point I ment integer sample processing, that means that the fractional part is zero length. But I already know that you fool your users and use float and double as an intermediate format.FaTony wrote:There is no fixed point types in ISO C++ and I'm not interested in platform specific hacks.
I can fix it because it depends on the current state of the program what to do in this case.FaTony wrote:Again, if cleanup fails, you can't fix it.
Or cleanup may be passed to special cleaning thread so the main thread won't block.FaTony wrote:If cleanup takes much time you too can't do anything to make it faster.
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
You can propose your solution to the standard committee.sadko4u wrote:I've already solved this by using macros (which are 'evil') and lambas. Syntax changed but still comfortable for use, without need of huge typing:
Are you doing I/O in destructors? The destructor should close whatever resource it holds. There shouldn't be any I/O.sadko4u wrote:Terminating application? You're serious? I should terminate application on probabale I/O error with sockets or filesystem? No, instead of this I can launch some process for fixing the problem or retry some amount of I/O operations. But this all requires some time, so the problem object/resource should be passed to another cleaning/fixing thread.
Tuples are compile time. It doesn't have overhead at runtime.sadko4u wrote:Really? And what about tuples? /usr/include/c++/4.8/bits/unique_ptr.h:Code: Select all
snip
It is required for thread safety. Remember, multithreading is now in ISO C++ so people need to think about thread safety.sadko4u wrote:Oh really? Let's look into /usr/include/c++/4.8/bits/shared_ptr.h and included files:You're trying to fool me? It has overhead of two counters and additionally of spinlock object. So each modification of shared_ptr causes atomic operations on shared data that are expensive.Code: Select all
snip
I pass reference to const. You can't modify const std::vector<std::string>.sadko4u wrote:Really? So you pass std::vector<std::string> to the function in hope that it won't modify strings from passed vector? This is called 'not brain dead'?
You can give anything but you wouldn't have anything more reputable than isocpp.orgsadko4u wrote:I can give another site that says contrary things. Don't try to citate somebody, give facts.
Here's the STL. Afaik Visual C++, libstdc++ and libc++ come without it.sadko4u wrote:As the counterpart I can add that there is currently no C++ provided without STL. From STL we get damn std::cout, std::cin and many other unusable stuff.
If you love your float* or double*, keep using them. I make abstractions that allow me to do many things with little code. To me, it's better to writesadko4u wrote:Oh, sorry, I thought it was shit. But now I see it is a complete shit:Tons of code that mostly do... nothing. Many-many-many abstractions to use finally float or double.Code: Select all
snip
Code: Select all
buffer += 6_dB
First, you forgot that there is also a long double. Second, you want me to copy paste the whole code of the library and have 3 copies of code that do the same thing with different types? Ever heard about scalability?sadko4u wrote:Or you can simply provide two overloaded functions that do same things in bulk mode with specified size of float instead of building huge template structure.
You are the only person that calls integers fixed point. I don't fool anyone because my library is fully documented.sadko4u wrote:Under fixed point I ment integer sample processing, that means that the fractional part is zero length. But I already know that you fool your users and use float and double as an intermediate format.
Provide a concrete example.sadko4u wrote:I can fix it because it depends on the current state of the program what to do in this case.
Yes, you can do this, but the time will still be consumed, no matter what thread does it.sadko4u wrote:Or cleanup may be passed to special cleaning thread so the main thread won't block.
You know, I'd love to go into your code and say that it's a complete shit, but I have better things to do.
- sadko4u
- Established Member
- Posts: 989
- Joined: Mon Sep 28, 2015 9:03 pm
- Has thanked: 2 times
- Been thanked: 361 times
Re: jack c++ API
I think I'm not the first and not the last who asks commitee about 'finally' statement. And I think I'm not the first and not the last whom the commitee will answer 'f*ck you' because I already saw the similar answers.FaTony wrote:You can propose your solution to the standard committee.
I'm not doing I/O in destructors. But I saw how many people DO it:FaTony wrote:Are you doing I/O in destructors? The destructor should close whatever resource it holds. There shouldn't be any I/O.
http://www.tomdalling.com/blog/software ... explained/
Alright, how I shall use spinlocks everywhere I want to share pointer between objects. Even I don't use them for multi-threading. Nice, optimal solution for time-critical applications!FaTony wrote: Tuples are compile time. It doesn't have overhead at runtime.
It is required for thread safety. Remember, multithreading is now in ISO C++ so people need to think about thread safety.
uinque_ptr doesn't allow copying. Also I can't use arrays on shared_ptr and weak_ptr, instead of this I should use vectors and so on... So the code falls into deep metaprogramming instead of doing something more useful.
Oh damn, these magic with references. Now const vector returns const reference to non-const data. Super! Fine! Did the original design of C++ expect this?sadko4u wrote:I pass reference to const. You can't modify const std::vector<std::string>.
Really? https://msdn.microsoft.com/en-us/library/cscc687y.aspx Alright, let's imagine STL is not coming-out-of-the-box for some compiler. And what you can do with it without STL? All your lovely meta-programming code (and highly propagated by other C++ adepts) that uses STL collections won't compile. It's like you would use C without glibc.FaTony wrote:Here's the STL. Afaik Visual C++, libstdc++ and libc++ come without it.
Or you can just write:FaTony wrote:If you love your float* or double*, keep using them. I make abstractions that allow me to do many things with little code.Code: Select all
buffer += 6_dB
Code: Select all
adjust_gain(buffer, 6_dB, samples);
Did you ever heard about optimizations? Each function can be tuned at low-level to boost performance up to numerous times (especially, by applying vectorization). When you instantiate templates, you have nothing to do with the generated code.FaTony wrote:First, you forgot that there is also a long double. Second, you want me to copy paste the whole code of the library and have 3 copies of code that do the same thing with different types? Ever heard about scalability?
Because integers are the special case of fixed-point values.FaTony wrote:You are the only person that calls integers fixed point.
And how do you handle 16-bit samples while adjusting 3dB gain?FaTony wrote:I don't fool anyone because my library is fully documented.
Concrete example: you're writing remote file via FXP protocol, then you perform the close() on remote handle. The close() fails on socket error. Now you have to execute code that will check that file was completely written if connection to the remote side is available. If it would be RAII, the usual solution (see the article above) would be 'call remote side for closing file handle' in destructor. You offered to crash program for this case. Very nice!sadko4u wrote:I can fix it because it depends on the current state of the program what to do in this case.
Right, but the main thread that serves something won't block instead of 'close-on-destruction' case.FaTony wrote:Yes, you can do this, but the time will still be consumed, no matter what thread does it.
I also don't have much time to explain where template programming could be good and where it's better not to use it.FaTony wrote:You know, I'd love to go into your code and say that it's a complete shit, but I have better things to do.
LSP (Linux Studio Plugins) Developer and Maintainer.
-
- Established Member
- Posts: 2347
- Joined: Mon Jul 01, 2013 8:13 am
- Has thanked: 9 times
- Been thanked: 466 times
Re: jack c++ API
Hi
Funny read here, a lot of pro and cons on both side, but, we all know, the world isn't black&white.
Best way to resolve things, is, do it your way.
However, one thing here brings me to response here, because I can't believe what I read, it's this stance:
http://www.dspguide.com/ch28/4.htm
and this
Funny read here, a lot of pro and cons on both side, but, we all know, the world isn't black&white.
Best way to resolve things, is, do it your way.
However, one thing here brings me to response here, because I can't believe what I read, it's this stance:
Ups, Fixed Point Processing, is a very well known, and widely used dsp therm.FaTony wrote:You are the only person that calls integers fixed point.
http://www.dspguide.com/ch28/4.htm
and this
there are a couple of need usage for templates, no reason to avoid them, even, no reason to pray them.sadko4u wrote:That's why I avoid templates where it's possible.
Code: Select all
template <class T>
inline std::string to_string(const T& t) {
std::stringstream ss;
ss << t;
return ss.str();
}
On the road again.
-
- Established Member
- Posts: 681
- Joined: Sat Nov 01, 2014 8:15 pm
- Location: The Internet
- Been thanked: 1 time
Re: jack c++ API
Amen to that. I'm tired of this discussion already.tramp wrote:Best way to resolve things, is, do it your way.