-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add rewrite support using libopusenc #23
Conversation
Puh. That is a big one.
|
For 4, you wrote in OpenWrt: ’I store voicemail recording as .opus files and send those out via email.’ From which source do you store them, are you recording within your Asterisk? |
|
(Wrong key, continuing...) |
|
Final comment for now, continuing the integer/float issue here: libopus indeed provides public API functions to feed either input data, libopusenc too has both public API functions: The patches here only use I can try to look into making libopusenc use integer pcm data directly, but I'd consider that an implementation detail of that library. For this PR it still makes sense to make the complexity and bitrate configurable, right? |
Mhm. First of all, that is not code created by me and I never used Opusfile before. Therefore, I have to research all that stuff myself first. Does the library store a pointer to the struct or copy the struct content? If I did not mis-read the source code of Opusfile, the struct content is copied. Therefore, heap or stack does not matter. However, I would be more happy to keep the struct on stack because a caller could create various combinations of those callbacks (yes,yes,null,null or yes,yes,yes,null or …). In other words: Can we drop that change? Or in other words: Why does it look suspicious exactly?
opus not. The referenced issue is about the codec module. Here, we are about the format module. Because you are the only one using it, you could even hard-code it. However, I would prefer a
Debian was just one example. libopusenc is not part of libopus or libopusfile but a third part. Even if it does exist, it may not be present. Therefore, we have to make it conditional somehow. If you need help for the built-in tree part, please, say so.
Interesting finding. Yes, you should at least report to libopusenc, as feature request. Then, one day someone adds it. Nevertheless, I wonder why Asterisk gives you non-float data. Does it convert the PCM stream internally already?
Yes, two new packages are required, libopusenc and libopusenc-dev. Not sure why that stucks. Nevertheless, a complete different story. |
Exactly because it's a temporary pointer, but if you already checked that the cb pointers get copied then it obviously works either way. Maybe I'm just more used to declare everything possible as static const, as that gets thrown in the .rodata elf section. Efficiency, attack surface, yada yada. Or maybe I just read kernel patches too often... Anyway, I'll drop it and don't forsee issues as you verified it's not just working by accident as-is.
Alright, will adapt accordingly
Okay, I'll make it conditional with
The module contains |
Just, HAVE_OPUSENC without the ‘LIB’, please. I then take care of the autoconf part.
That means, you get slin48? With PCM as source, I would have expected slin. Does Asterisk up- and down-sample? |
Sure, HAVE_OPUSENC then. And yes, IIRC alaw in is 8khz, and 48khz is what opus want, so asterisk upsamples by a nice round factor of 6 (didn't verify how efficiently that is implemented) |
Please, double-check that. In the codec module, I am feeding 8 kHz directly, if the source is 8 kHz. If I am not totally mistaken. That way, I do not have to upsample and Opus uses one of its 8 kHz formats internally. Or was it the sample rate? Ohh … normally I am on a complete different abstraction layer, I forget about such stuff. Please, check again, because all conversion stuff it eating resources on your OpenWrt device. |
If you feed it !=48khz it resamples itself: https://github.com/xiph/libopusenc/blob/master/src/opusenc.c#L432 |
Updated:
|
Yes, correct. My fault.
OK. However, the Makefile still requires/enables libopusenc. I am think about making that conditional … any idea for that without going for a full-blow configure script? |
I think, we leave the Makefile as is, except you have a great idea. If someone uses the Makefile and has libopusenc not installed, please, report! Then, we are going to find a solution together. By the way, to build and install libopusenc in Debian/Ubuntu, for example, you go for
@dhewg the source passed all my (compile-time) tests. However, I found one issue in the struct. Can you confirm, that it still works that way? I cannot test run-time so easily. Otherwise, we have to find another approach to avoid compiler padding. |
formats.conf is parsed to allow setting two encoder settings: [opus] complexity=4 maxaveragebitrate=20000
libopusenc is an optional library, auto-detected by the script ./configure. That script gets patched by `asterisk.patch`. That patch is changed once this Pull Request is merged.
For example, the compiler Clang 13 warned about padding struct 'struct ogg_opus_desc' with 4 bytes to align 'writing_pcm_pos' [-Wpadded].
I added a compile-time option for the Makefile to toggle this feature. |
The symbol ast_format_get_channel_count got introduced with Asterisk 15. This module has to be compatible with Asterisk 13 and newer.
Asterisk 13.19.0 added Opusfile with /asterisk/asterisk/commit/b5331af Consequently, there is no need to patch that in anymore. However, libopusenc has to be (optionally) detected now.
Changed the code a bit towards my own and the Asterisk Coding Guidelines. Furthermore, I added the autotools stuff, so it builds in-tree. Finally, I tested and fixed the code Asterisk 13, again just compile-time, not runtime. The last remaining test is going to be iwyu. But not today.
Great. Yepp, that is easy for a user.
That is a question for StackOverflow. I learned, automatic padding is not good because it is not cross-platform safe. The problem with an |
Nice, looks all good to me! |
* fcntl, frame, and logger were missing before * utils was not used before * utils and config are used only if libopusenc is enabled * format was missing
iwyu is helpful as final test especially in complex architectures like Asterisk. I took over this source file, never tested it at runtime, and did not touch it before. iwyu found three headers which were missed before this change here already. With the addition of libopusenc, just one header was missing. Furthermore, iwyu found an unused header. However, that got used with the addition of libopusenc now. Did I mention that I like iwyu? Running the Debian/Ubuntu packaged iwyu is a bit tricky because you have to know and then install its version of Clang, the version that was used to build iwyu by the package maintainer. More about this here … Then, before you run iwyu, build Asterisk, and then go for
Explanation: Clang needs the block-function extension for Asterisk, therefore Because we have a compile time switch in the source now, iwyu must be run twice, with an without defined. To test the latter, I simply removed the definition of |
Nice, thanks! |
Was a pleasure. Because of this, even issues in other projects were found. For example, while code-reviewing, I had to look-up the documentation. On Opus-Codec.org, the HTML documentation was broken for libopusenc, for more than a year. Fixed now. And because that was a generic issue, more projects benefited from analyzing the cause. Lesson learned: You never know what you start with an issue on GitHub. If you have other code or ideas, just open requests/issues. And do not forget to update and continue with your down-stream issue openwrt/telephony#693 |
This contains a small clean-up patch and adds support to rewrite .opus files.
In my case I store voicemail recording as .opus files and send those out via email.
codecs.conf
is parsed to allow setting two encoder settings: